I was trying to see if element enabled on the page before clicking on that. I want to create command that will check if element is enabled or not before clicking on it. I was going over API of nightwatch and still not sure how this commands works. I was trying following:
browserObj.elementIdEnabled(Cssselector, function (res) {
console.log(res);
});
But I think I should pass something else and not css selector into elementIdEnabled function. Ideally I want to chain 3 commands before clicking on element:
browserObj.perform(function () {
this.waitForElementPresent(cssSelector, timeout, function () {
this.waitForElementVisible(cssSelector, timeout, function () {
this.api.elementIdEnabled(cssSelector, function (res) {
browserObj.click(cssSelector, function (clickStatus) {
this.assert.equal(clickStatus.status, 0 );
});
})
})
});
});
module.exports.command = function (selector) {
this.waitForElementVisible(selector).click(selector);
return this;
};
By beatfactor from
https://github.com/nightwatchjs/nightwatch/issues/705
Related
I have a problem with selecting element after generating by async callback function.
How to do that?
My code:
$(document).ready(function() {
function1(function2);
//here i want to select generated element by id $('#select-id')
});
function function1(callback) {
$.getJSON('./ajax/results_get.php', function(data) {
console.log("function1");
callback();
});
}
function function2() {
console.log("function2");
}
EDIT:
Now i used callback, but i don't know how to make visible object created within function3 to the click button event.
$(document).ready(function() {
function1(function() {
function2(function() {
function3(function(){
var foo = $('#element');
});
});
});
$('#savebtn').click(function(){
//how to use assigned foo here?
});
});
I'm trying to get the news comments on yahoo, where there is a link "See reactions", with the following id: "caascommtbar-wide" and tried to get the element with CasperJS, Selenium, ScrapySharp, to click on the link and display the comments, but in those tools you never find the element and I've even tried using the XPath
CasperJS:
casper.then (function () {
if (this.exists ('a.caascommtbar-anchor')) {
this.echo ("It exists");
} else
this.echo ("It Does not Exist");
});
casper.then (function () {
// Click on 1st result link
this.click ('a.caascommtbar-anchor');
});
Selenium:
driver.FindElement (By.Id ("caascommtbar-anchor")). Click ();
Does anyone know why you can not access this part of the HTML code where the comments are located?
It should be noted that the same thing happens to me when trying to access the Facebook comments contained in the news forums.
As Isaac said the part of pages are loaded asynchronously, so you should implement waitFor steps in your code. Here is the code that does just that.
var url = "https://es-us.vida-estilo.yahoo.com/instagram-cierra-la-cuenta-de-una-modelo-por-ser-gorda-103756072.html";
var casper = require('casper').create({
viewportSize: {width: 1280, height: 800},
});
casper.start(url, function() {
this.echo('Opened page');
});
casper.waitForSelector('a.comments-title', function() {
this.click('.comments-title');
});
casper.waitForSelector('ul.comments-list > li', function() {
this.echo(this.getHTML('ul.comments-list'));
});
casper.run();
Hope that helps
The problem was why the page was not loaded yet and I had to wait, I'm new with casperjs.
Now I have the problem when trying to remove all comments along with their answers, but can not find an algorithm to help me. Try to press all the answer buttons, but only get the first answers to the first comments.
casper.waitForSelector('button.showMore', function () {
this.click('.showMore');
}, function onWaitTimeout() {
});
var buttons;
casper.waitForSelector('ul.comments-list', function getLinks() {
buttons = this.evaluate(function ()
{
var buttons = document.getElementsByClassName('replies-button');
buttons = Array.prototype.map.call(buttons, function (button) {
button.click();
casper.waitForSelector('ul.comments-list', function () {
casper.wait(3000, function () {
});
});
return button.getAttribute('class');
});
return buttons;
});
}, function onWaitTimeout() {
});
function wait5seconds() {
casper.wait(3000, function () {
});
}
casper.waitForSelector('ul.comments-list > li', function () {
var x = this.getHTML('ul.comments-list');
this.echo(x);
}, function onWaitTimeout() {
});
casper.run();
I have this function below. It's a simple loop that look over a list of projects. For each project, it makes a NeDB query (does not matter here, just consider that it works as an Ajax function) that retrieve the tasks corresponding to the project and then display the tasks and an Edit button.
function myFunction() {
console.log('Work');
}
$.each(projects, function( index, project ) {
// tasks.find takes 100ms, it's like an Ajax request
tasks.find({}, function (err, tasklist) {
$('#my-list').append('<li>Edit</li>');
});
});
I would like that when I click on Edit, it runs myFunction().
So usually, I would have used on click like this :
function myFunction() {
console.log('Work');
}
$.each(projects, function( index, project ) {
// tasks.find takes 100ms, it's like an Ajax request
tasks.find({}, function (err, tasklist) {
$('#my-list').append('<li>Edit</li>');
$('#my-list li').on('click', function(){
myFunction();
}
});
});
The problem is that the on click function is in a loop, so it creates the function for each iteration of the loop, so it print 'Work' as many times as there are projects.
I also tried this
$('#my-list').append('<li onClick="myFunction()">Edit</li>');
But it does not recognize my function
What is the solution ?
We should only listen to click event of 1 <li> element
function myFunction() {
console.log('Work');
}
$.each(projects, function( index, project ) {
// tasks.find takes 100ms, it's like an Ajax request
tasks.find({}, function (err, tasklist) {
var $newLi = $('<li>Edit</li>');
$newLi.appendTo('#my-list');
$newLi.on('click', function(){
myFunction();
}
});
});
Hope that this can help :)
Change your on.click functionality to:
$("#my-list).on("click", function(e) {
// You can access the specific element child clicked
// by using $(e.target);
myFunction();
})
I'm super confused by my code. Let me show what it looks like:
$(document).ready(function ($) {
var customer_exists = false;
$.get(window.additional_parameters.customer_exists_url, "json")
.done(function () {
customer_exists = true;
})
.always(function () {
// Don't make request to buy clickable until we know if the customer exists
$('#request-to-buy').on('click', function(e) {
request_to_buy(customer_exists);
});
});
function request_to_buy(customer_exists) {
response = can_request_to_buy();
response.done(function (response) {
if (customer_exists) {
// Actually create the request on the server
$.post(window.additional_parameters.request_to_buy_url,
{'ticket_id': window.additional_parameters.ticket_id},
"json")
.done(function (response) {
request_to_buy_success(response);
})
.fail(function () {
var message = handle_ajax_response(response);
show_ajax_message(message);
});
} else {
show_pre_stripe_popup();
}
})
.fail(function (response) {
var error_message = handle_ajax_response(response);
show_ajax_message(error_message, 'danger');
});
}
$(document).ready(), we set a variable called customer_exists. This variable guides the path of the code afterwards and is pretty important. If the $.get AJAX request is successful, it's true, otherwise it remains it default value of false. After the AJAX response, we attach a click event to "#request-to-buy." My goal here is to create a closure and pass in the value of customer_exists that was just set. This doesn't happen.
A good portion of the time ( I had it work correctly once or twice ), when I inspect request_to_buy in the debugger, I can see that customer_exists is a jQuery click event. why ??? Shouldn't it take on the value of the customer_exists from the surrounding scope of where the function was created? Can anyone explain what is going on here?
Thank you
EDIT: Here's a little more information that describes how it works sometimes...
The first time that I click '#request-to-buy', the handler is
function(e) {
request_to_buy(customer_exists);
}
This is what we would expect. e contains the click event, customer_exists retains it's value, and everything works inside request_to_buy.
Every time I click '#request-to-buy' after the first, instead of the above function being called, request_to_buy is called directly, and instead of passing in customer_exists in the first parameter, the click event is passed in instead. I hope this helps someone.
You should be able to do this without the need for the cumbersome outer var customer_exists.
For example :
$(document).ready(function ($) {
$.get(window.additional_parameters.customer_exists_url, "json").then(function () {
// Don't make request to buy clickable until we know if the customer exists
$('#request-to-buy').on('click', request_to_buy);
}, function() {
$('#request-to-buy').on('click', show_pre_stripe_popup);
});
function request_to_buy(e) {
e.preventDefault();
can_request_to_buy().then(function(response) {
// Actually create the request on the server
$.post(window.additional_parameters.request_to_buy_url, {
'ticket_id': window.additional_parameters.ticket_id
}, "json").then(request_to_buy_success, function() {
show_ajax_message(handle_ajax_response(response));
});
}).fail(function(response) {
show_ajax_message(handle_ajax_response(response), 'danger');
});
}
}
show_pre_stripe_popup will also be passed an event and you may need to do e.preventDefault(); there too.
You will need to check that the correct parameters are passed to the various error handlers. I can't verify them.
If it still doesn't work, then you must suspect other code that's not included in the question, for example the function can_request_to_buy().
var customer_exists = false;
Declare this outside of ready block.
I have two files - main, and events. I'm trying to call some function from one file to another.
So, this is how it looks:
events
require(['app/main'], function(call) {
// click event respond test
document.body.addEventListener("click", function(e) {
var target = e.target;
if (target.hasClass === "call"){
functionCall()();
}
});
});
main
define(["jquery"], function() {
// Call
var box = $('.box');
return function functionCall(){
box.addClass('visible');
}
});
What is wrong, can anyboyd help?
main:
define(["jquery"], function($) {
var main = {
functionCall: function(){
$('.box').addClass('visible');
}
}
return main;
});
events:
require(['jquery','app/main'], function($, main) {
$('body').on('click', function () {
if($(this).hasClass('call')){
main.functionCall();
}
});
});
One way is to add this code where you need to make call to function:
require('pathToModuleOrModuleName').functionYouWantToCall()
But if you have module defined or required in the beggining (as 'main' in the events), then in place where call to function needed just add:
call.functionName();
Unless my eyes deceive me the simplest change to make to your code would be to replace this:
functionCall()();
with this:
call();
since the function that the main module returns is imported as call in your events module, because that's how you name it in the callback passed to define.
Firstly your code has some basic problems
In the following code
define(["jquery"], function() {
Where are you referring the query inside the function definition.
I think you should first map the jquery defined into the function declaration like below
define(["jquery"], function($) {
Secondly, what is the () doing after the calling function?
if (target.hasClass === "call"){
functionCall()();
}
Remove the trailing () from that call. It should just be functionCall();