Here's my HTML, which is present and valid. When I break on the testcases using WebStorm, I can inspect the page and see this element just fine...
<a id="privacyPolicy1234" on-tap="goPrivacyPolicy()" class="disable-user-behavior">Privacy Policy</a>
Here is my Jasmine test, which is failing to find the element.
it("should list a privacyPolicy ", function() {
privacyPolicyElement = element(by.id('privacyPolicy1234'));
expect(privacyPolicyElement.getText()).toContain("Privacy Policy");
The error coming back
Message:
NoSuchElementError: No element found using locator: By.id("privacyPolicy1234")
edit:
Also tried to put it in one line, and getting false where I expect true
expect(element(by.id('privacyPolicy1234')).isPresent()).toBe(true);
Instead of a browser.sleep() which makes the test non-reliable and slower, use an explicit wait. For instance, you can wait for the "privacy policy" element to become present:
var EC = protractor.ExpectedConditions,
privacyPolicyElement = element(by.id('privacyPolicy1234'));
browser.wait(EC.presenceOf(privacyPolicyElement), 5000);
expect(privacyPolicyElement.getText()).toContain("Privacy Policy");
It's important to note that in this case protractor would wait up to 5 seconds, checking the presence of the element every 500 ms (by default). Once the condition is met, it stops waiting. If after 5 seconds, the element would still not become present - you'll get a timeout exception.
Turns out, I'm testing the page before it loads..
as a work around I added
it("should list a privacyPolicy ", function() {
browser.sleep(2000);
privacyPolicyElement = element(by.id('privacyPolicy1234'));
Related
Hello I want to try to run all of these code on console chrome
var xxx = document.querySelectorAll('.balanceDetails-manageCurrencies.test_mcm-addCurrency')
xxx.forEach(btn => btn.click())
var twd = document.querySelectorAll('.shadow.multiCurrency-flag.multiCurrency-flag_TWD')
twd.forEach(btn => btn.click())
var addcurrency = document.querySelectorAll('.btn.vx_btn.mandate_lg-btn.test_mcm-addCurrencyButton')
addcurrency.forEach(btn => btn.click())
But it doesnt run everything, the process just stop when they excute line number 2
xxx.forEach(btn => btn.click())
Question is, how to run all of these code?
Try combining the arrays then running the click loop on the new array.
replace sel1 etc to your selectors
var xxx = [...document.querySelectorAll(sel1), ...document.querySelectorAll(sel2), ...document.querySelectorAll(sel3)]
xxx.forEach(el => el.click())
It's hard to tell what's going on in your case because we don't know what your selected DOM nodes are doing after being clicked. If you paste that entire code block into the chrome console I would expect it to execute all of it.
Two things off the top of my head could be happening.
The click handler setup to fire on one of those DOM nodes is throwing an error, but that error is being caught by a try/catch block and never bubbles up to the console. This would create the symptoms described.
The click handler for one of those DOM nodes is doing a form post, or something else that will cause the page to reload. Although, if this were the case you'd see the console clear. Not sure if you're seeing that or not.
I'm using Protractor (with Javascript) to run my automatic tests.
Sometimes happen that a test fails cause it can't find an element that is present on the page.
My Html:
<div class="card-date">05 Dec</div>
My Steps definitions:
Then('I see a card-date', {timeout: 50*1000} , function (next) {
var card_date = element(by.css('.card-date'));
expect(card_date.isPresent()).to.eventually.be.true.and.notify(next);
});
My Attempt with browser.wait in the step definition:
Then('I see a card-date', {timeout: 50*1000} , function (next) {
var card_date = element(by.css('.card-date'));
var expected = protractor.ExpectedConditions;
browser.wait(expected.visibilityOf(card_date));
expect(card_date.isPresent()).to.eventually.be.true.and.notify(next);
next();
});
I tried with this too:
browser.driver.wait(function() {
return card_date.isDisplayed().then(function(IsVisible) {
return IsVisible;
});
}, 10000);
expect(card_date.isPresent()).to.eventually.be.true.and.notify(next);
Error:
AssertionError
+ expected - actual
-false
+true
I tried to recover the text of the element by managing promise, so i could have the length of the string of the element and checks if it is a number above 0. If this condition is true, the element is obviously present. But when I launch the test, it can't read inside my promise. The console log is never shown on my console.
Why this is happen if the element is present on the page??
At the moment of the fail I can see the browser opened normally in the right page and the element is always present.
I'm using wedriverio 4.5:
./node_modules/.bin/wdio -v
v4.5.2
I need to wait until some element exists and if it doesn't exist handle this situation.
for example:
let element = browser.element('.unexisting');
browser.waitUntil(
function () {
return element.isExisting();
},
1000,
'Element is not found.'
);
But if element doesn't exist on the page, webdriver marks my test as failed and shows message: 'Timeout of 10000ms exceeded. Try to reduce the run time or increase your timeout for test specs (http://webdriver.io/guide/testrunner/timeouts.html); if returning a Promise, ensure it resolves.'
How can I handle this situation?
I tried try-catch block, but anyway I see same message about timeout and failed test.
I tried element.waitForExist() but behavior is the same
I tried to use error handler (but it doesn't help)
browser.on('error', function(e) {
console.log ('handle browser error');
})
Why don't I see my message 'Element is not found.'?
Thanks!
Make sure your waitForXXX command doesn't take longer than your spec timeout. If it does increase your spec timeout, in your case mochaOpts.timeout. See more here http://webdriver.io/guide/testrunner/timeouts.html#Framework-related-timeouts
I'm using Selenium/Chromedriver via Protractor. I'm switching to an iframe, waiting for the contents to load, and then planning to manipulate elements inside it. But it's never recognizing that the contents have loaded.
browser.driver.switchTo().frame("myView");
browser.driver.wait(function() {
return browser.driver.isElementPresent(by.id("myDiv"))
.then(function (isPresent) {
return isPresent;
});
}, 20000, "Taking too long to load!");
myDiv is definitely present within 20 seconds, but wait() times out.
I've tried switching to using browser.driver.findElement(), but got the same result.
I've made sure I'm updated to Chromedriver 2.21 (which fixed an earlier error).
Any ideas what else I could be doing wrong?
ETA per comment: This is all I'm getting for an error log...
Message:
Error: Taking too long to load!
Wait timed out after 20069ms
Stacktrace:
Error: Taking too long to load!
Wait timed out after 20069ms
==== async task ====
Taking too long to load!
at /Users/me/Documents/My-Test/specs/myWorkflow.js:82:20
==== async task ====
at [object Object].<anonymous> (/Users/me/Documents/My-Test/specs/myWorkflow.js:79:14)
==== async task ====
Asynchronous test function: it()
Error
at [object Object].<anonymous> (/Users/me/Documents/My-Test/specs/myWorkflow.js:7:5)
at Object.<anonymous> (/Users/me/Documents/My-Test/specs/myWorkflow.js:5:1)
I've gotten around similar issues by adding a sleep statement, instead of using a wait loop. In c# I would use thread.sleep(20000); for a 20 second wait. Most of mine are in the 1 to 5 second range.
To clarify: I'm suggesting removing the loop that is he is using to check for the element and instead using a simple sleep type command then interacting with the element.
In Selenium using C# I have used the following statement to provide a fixed wait time while an element loads before clicking the element. This element happens to be a link, but it can be any element
//sleep time so UX can load
Thread.Sleep(3000);
//open the new form
By newButton = By.XPath("/dummy/xpath");
IWebElement button = driver.FindElement(newButton);
button.Click();
I noticed that qUnit doesn't give any notice when an exception happens in a later part of the test. For example, running this in a test():
stop();
function myfun(ed) {
console.log('resumed');
start(); //Resume qunit
ok(1,'entered qunit again');
ok(ed.getContent()== 'expected content') // < causes exception, no getContent() yet.
}
R.tinymce.onAddEditor.add(myfun)
in an inner iframe on the page will cause an exception (TypeError: ed.getContent is not a function),
but nothing in Qunit status area tells this. I see 0 failures.
(R being the inner iframe, using technique here: http://www.mattevanoff.com/2011/01/unit-testing-jquery-w-qunit/) Would I be correct in assuming this isn't the best way to go for testing sequences of UI interaction that cause certain results? Is it always better to use something like selenium, even for some mostly-javascript oriented frontend web-app tests?
As a side note, the Firefox console shows the console.log below the exception here, even though it happened first... why?
If you look into qUnit source code, there are two mechanisms handling exceptions. One is controlled by config.notrycatch setting and will wrap test setup, execution and teardown in try..catch blocks. This approach won't help much with exceptions thrown by asynchronous tests however, qUnit isn't the caller there. This is why there is an additional window.onerror handler controlled by Test.ignoreGlobalErrors setting. Both settings are false by default so that both kinds of exceptions are caught. In fact, the following code (essentially same as yours but without TinyMCE-specific parts) produces the expected results for me:
test("foo", function()
{
stop();
function myfun(ed)
{
start();
ok(1, 'entered qunit again');
throw "bar";
}
setTimeout(myfun, 1000);
});
I first see a passed tests with the message "entered qunit again" and then a failed one with the message: "uncaught exception: bar." As to why this doesn't work for you, I can see the following options:
Your qUnit copy is more than two years old, before qUnit issue 134 was fixed and a global exception handler added.
Your code is changing Test.ignoreGlobalErrors setting (unlikely).
There is an existing window.onerror handler that returns true and thus tells qUnit that the error has been handled. I checked whether TinyMCE adds one by default but it doesn't look like it does.
TinyMCE catches errors in event handlers when calling them. This is the logical thing to do when dealing with multiple callbacks, the usual approach is something like this:
for (var i = 0; i < callbacks.length; i++)
{
try
{
callbacks[i]();
}
catch (e)
{
console.error(e);
}
}
By redirecting all exceptions to console.error this makes sure that exceptions are still reported while all callbacks will be called even if one of them throws an exception. However, since the exception is handled jQuery can no longer catch it. Again, I checked whether TinyMCE implements this pattern - it doesn't look like it.
Update: Turns out there is a fifth option that I didn't think of: the exception is fired inside a frame and qUnit didn't set up its global error handler there (already because tracking frame creation is non-trivial, a new frame can be created any time). This should be easily fixed by adding the following code to the frame:
window.onerror = function()
{
if (parent.onerror)
{
// Forward the call to the parent frame
return parent.onerror.apply(parent, arguments);
}
else
return false;
}
Concerning your side-note: the console object doesn't guarantee you any specific order in which messages appear. In fact, the code console.log("foo");throw "bar"; also shows the exception first, followed by the log message. This indicates that log messages are queued and handled delayed, probably for performance reasons. But you would need to look into the implementation of the console object in Firefox to be certain - this is an implementation detail.