Nightwatch 'For' Loop not executing commands - javascript

I'm trying to create a loop within nightwatch.js that will;
load a page
assert an element
click on this element
for a selection of pages.
Below is my code;
var carTypeHref = ['/type-hatchback/','/type-saloon/','/type-estate/','/type-4x4/']
var listCarTypeHref = carTypeHref[Symbol.iterator]();
module.exports = {
'navigate to small car type cfs landing page': function (browser) {
browser
.url(browser.launch_url + browser.globals.carsForSale + '/type-small-city/')
.agreeCookiePolicy();
},
'navigate to car type cfs landing pages and check dealer link details': function (browser) {
for (let carType of browser.globals.listCarTypeHref) {
browser
.url(browser.launch_url + browser.globals.carsForSale + (carType))
.assert.elementPresent('.for-sale-result-item__dealer')
.click('.for-sale-result-item__dealer')
}
},
'closing the browser': function (browser) {
browser
.browserEnd();
},
};
The urls load correctly, one by one as defined in carTypeHref and listCarTypeHref.
However, the rest of the commands within this loop don't appear to be executed;
.assert.elementPresent('.for-sale-result-item__dealer')
or
.click('.for-sale-result-item__dealer')
are not executed.
I'm a bit stuck as to why, so any help would be appreciated.
Thanks.

Related

Javascript: how to execute a function within a function without delay?

I'm trying to make an automated image gallery using javascript to paste img-statements (+ some extras for css) into html.
All the images are in the same folder and are named image (1), image (2), ... Apparently client side can't know the name of the files in the folder nor the amount of files.
The append-process works fine, but I can't find a way to stop without giving the amount of pictures myself.
I'm trying to stop the append-process using ".onerror" when the browser can't find the next image, but it is always skipped until the end (resulting in an infinite loop (I'm using a "i<=6" for testing)).
Thanks! Here is my code:
function showgallery() {
let flag = true;
let i = 1;
while (i <= 6 && flag) {
$("#fotos").append(`<div class="cssbox">
<a id="image${i}" href="#image${i}"><img id="picture${i}" class="cssbox_thumb" src="../photogallery/image (${i}).jpg">
<span class="cssbox_full"><img src="../photogallery/image (${i}).jpg" /></span>
</a>
<a class="cssbox_close" href="#void"></a>
<a class="cssbox_prev" href="#image${i-1}"><</a>
<a class="cssbox_next" href="#image${i+1}">></a>
</div>`);
document.getElementById(`picture${i}`).onerror = () => {
flag = false;
}
i++;
}
}
window.onload = showgallery;
The reason why it's skipping some is because it takes time to load each image and for onerror to be called, yet you are doing this all in a loop which executes all the code without waiting for the error, so even if there is an error the flag variable won't be changed until the error event is fired, which happens after the current loop cycle
The way to do this instead is use recursion, if a certain condition is not met yet. Also I would recommend using Image for testing then appending it to the document
Also you don't even need error you can just only append it if it loads successfully
So you can use recursion here like
var cur = 0
function getImg() {
var img= new Image ()
img.src = "image (" + (cur++) + ").jpg"
img.onload = () => {
fotos.appendChild(img)//or other span elements etc that have img as a child
getImg()
}
//if you want to know when it ended then you can use .onerror
img.onerror = () => console.log("done")
}
getImg()

How to find specific JavaScript code in parsed HTML using cheerio with nodejs?

I want to find a single JavaScript code/keyword like zopim or v2.zopim.com in whole script with using cheerio on NodeJS. I wrote a script that grabs all links from a single web site but the script need to opens all these grabbed links and search for "zopim" keyword in JavaScript codes. I looked cheerio's repository and it's issues but no luck. I'm wondering could anyone help me to figure out this situation?
This is a part of my code that where I open links and search in source code for a keyword. I can post all of it if it's necessary.
function () {
//console.log(totalUrls);
console.log("Crawling is done.")
if (page == 16) {
console.log("Anaylzing web sites...");
async.whilst(
function () {
return checkedUrl < totalUrls.length;
},
function (urlCallback) {
var currentUrl = totalUrls[checkedUrl]
request(currentUrl, function (err, res, body) {
if (err) {
console.log('Error: ' + err);
}
var $ = cheerio.load(body);
$('.headerContent').each(function () {
var title = $(this).find('a').text();
console.log(currentUrl + title);// if the current web site has a '.headerContent' class print it.
// I want to print only if web site source code includes "zopim" keyword in JavaScript code
});
checkedUrl++;
urlCallback();
});
}
);
}
}
You can use :contains selector to find scripts which contain keyword 'zopim' in text and then count found script elements:
const scriptsWithKeywordCount = $('script:contains("zopim")').length;
if (scriptsWithKeywordCount > 0) {
// webpage contains keyword in javascript code
}

Code behind Content editor button for Experience editor button

Is it possible to use a code behind of a command used for ribbon button in content editor as a request for experience editor button? We want to stick to SPEAK and not make any changes to Sitecore.ExperienceEditor.config.
After creating new button in Experience editor, telling .js to call NewCommand request by
Sitecore.ExperienceEditor.PipelinesUtil.generateRequestProcessor("ExperienceEditor.NewCommand");
that was referenced in Sitecore.ExperienceEditor.Speak.Requests.config as
<request name="ExperienceEditor.NewCommand" type="Sitecore.Starterkit.customcode.MyCommand,MyProject"/>
nothing happens and logs say
ERROR Could not instantiate speak request object,
name:ExperienceEditor.NewCommand,
type:Sitecore.Starterkit.customcode.MyCommand,MyProject`
Do we have to import PipelineProcessorRequest as suggested by some tutorials or is there a way to use our existing code?
Have you seen this blog post on adding custom SPEAK command buttons to Sitecore 8 Experience Editor?
https://doc.sitecore.net/sitecore%20experience%20platform/the%20editing%20tools/customize%20the%20experience%20editor%20ribbon
Otherwise if that doesn't achieve what your looking for, it might be worth trying to standard SPEAK application way of triggering a button, In a SPEAK application you can call a JavaScript function from a button click using this code.
javascript:app.FunctionName();
In the core DB update the click field on your button to call JavaScript with the javascript: prefix. Does this allow you to trigger your JavaScript?
I was able to use my existing control using guidelines from:
http://jockstothecore.com/sitecore-8-ribbon-button-transfiguration/
Relevant pieces of the old command:
if (args.IsPostBack)
{
// act upon the dialog completion
if (args.Result == "yes")
{
Context.ClientPage.SendMessage(this, "item:load(...)");
}
}
else
{
// trigger the dialog
UrlString url = new UrlString(UIUtil.GetUri("control:CopyLanguage"));
url.Add("id", item.ID.ToString());
url.Add("lang", item.Language.ToString());
url.Add("ver", item.Version.ToString());
SheerResponse.ShowModalDialog(url.ToString(), true);
args.WaitForPostBack();
}
The redressed command:
define(["sitecore"], function (Sitecore) {
Sitecore.Commands.ScoreLanguageTools = {
canExecute: function (context) {
return true; // we will get back to this one
},
execute: function (context) {
var id = context.currentContext.itemId;
var lang = context.currentContext.language;
var ver = context.currentContext.version;
var path = "/sitecore/shell/default.aspx?xmlcontrol=CopyLanguage" +
"&id=" + id + "&lang=" + lang + "&ver=" + ver;
var features = "dialogHeight: 600px;dialogWidth: 500px;";
Sitecore.ExperienceEditor.Dialogs.showModalDialog(
path, '', features, null,
function (result) {
if (result) {
window.top.location.reload();
}
}
);
}
};
});

javascript class killing app

just a quick one, im using a oop style for my javascript game but for some reason when i add in a new class it kills any functions from other classes i have included.
Here is the script i am talking about which is my main file which i will include all my class files in:
$(document).ready(function(){
var canvas = document.getElementById("TBG");
var context = canvas.getContext("2d");
var ui = new Gui();
// var level = new Level();
//----------Login/Register Gui --------------
$('#TBG').hide();
$('#load-new').hide();
$('#reg').hide();
$('#login').hide();
//if login_but is clicked do ui.login function
$('#login_but').click(ui.login);
//if reg_but is clicked do ui.register function
$('#reg_but').click(ui.register);
$('#new_but').click(function(){
game_settings("new");
});
$('#load_but').click(function(){
game_settings("load");
});
//if login_sumbit button is clicked do ui.login_ajax function
$("#login_submit").click(ui.login_ajax);
$("#reg_submit").click(ui.register_ajax);
$("#welcome").on("click", "#logout_but", ui.logout);
//___________________________________________________________________
//Initialisation of game
function game_settings(state){
if(state == "load"){
ui.load_game();
//do ajax call to load user last save
level.level_init(0,1);
}
else{
//set beginning params
//Change screens
ui.new_game();
alert("new game");
}
}
});
in the context of the script above, my problem is when i just have the call to new Gui() without the call to new level underneath or commented like you can see, well then all of the functions below under the heading login/register gui works perfectly, but as soon as i put the call to new level in or uncomment it, it kills all of the functions under the login/ register gui heading.
Why is this?
EDIT: here is the level.js file in case you would like to see it and how i am constructing my classes:
function Level(){
this.level_init = function(level, location){
var saved_level = level;
var saved_location = location;
};
this.get_tileset = function(){
};
this.draw = function() {
}
}
Thanks
Tom
SOrry guys, it turns out it was a silly mistake on my behalf i didnt add the script in html!, i need more sleep i think haha! thanks for your input
TOm

javascript run function with adobe air

I am working on the adobe air with javascript and html. I want to run multiple functions in a function with show the percentange run on the each function but the percentage also show the last calculation please help me.
Edit: added code snippet from comment, but I may have butchered the layout.
function show_percentage() {
down_admin()
down_staff()
down_client() }
function down_admin() {
down all information of admin from the server; flag=1; }
function down_staff() {
down all information of the staff falg=2; }
we want to calculation show the every after loaded functions. as percentage=25% to 100%
If you downloading several types of info and want to show summary progress, first you need to know bytes total of each download. When you get ProgressEvent from each operation, you may call function show():
function show() {
var progress = (adminBytesLoaded + staffBytesLoaded + clientBytesLoaded) * 100 /
(adminBytesTotal + staffBytesTotal + clientBytesTotal);
//show progress somehow
}
Update: some clarifications
Load resource you need with Loader. Add event listener to ProgressEvent on Loader.contentLoaderInfo. There will be three listeners for three load operations - load admin data, client data and staff data. When you get progress event from each operation (track it with three vars), you will know download size total:
var adminTotal:int;
var clientTotal:int;
var staffTotal:int;
var adminLoaded:int;
var clientLoaded:int;
var staffLoaded:int;
function onAdminLoadProgress(event:ProgressEvent):void
{
adminLoaded = event.bytesLoaded;
adminTotal = event.bytesTotal;
//if other operations already going, show progress
if (clientTotal && staffTotal)
{
showProgress();
}
}
function onClientLoadProgress(event:ProgressEvent):void
{
clientLoaded = event.bytesLoaded;
clientTotal = event.bytesTotal;
if (adminTotal && staffTotal)
{
showProgress();
}
}
//write onStaffLoaded yourself as an exercise :)))
I'm assuming you will make single request for each of those three downloads.

Categories