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();
Related
I am maintaining a react project that uses Cypress. Cypress by default is asynchronous. How to perform next cy commands while the above cy command is still processing?
Example:
cy.get('showDialog').click() // Instantly closes due to some react states
cy.get('showDialogCloseButton').click() // still loading looking for showDialogCloseButton which eventually fails
// need to execute this again to show dialog and complete above cy command:
cy.get('showDialog').click()
However, the last command can't be executed since it needs the above command to be finished (which resulted to failure)
Using cy.wait() after the cy.get('showDialogCloseButton').click()
ex:
cy.get('showDialogCloseButton').click();
cy.wait(1000);
With this 3rd command will execute after 1s, always
but will make your test suite unnecessarily slow.
So then you can try by increase the timeout(s)
cy.get('showDialog',{timeout: 30000}).click({timeout: 30000});
This command will only fail after 30 seconds of not being able to find the object, or, when it finds it, 30 seconds of not being able to click it.
You can try your own timeout
So you can easily do that with validate also,
cy.get('showDialog', { timeout: 30000 }).should('be.visible').then(() => {
cy.get('showDialog').click();
})
I am testing a web app and the test runs reliably in headed mode (cypress open) but has errors in headless mode (cypress run), so it's likely a race condition that I cannot resolve. The error message is:
[36819:0223/163815.745047:ERROR:system_services.cc(34)] SetApplicationIsDaemon: Error Domain=NSOSStatusErrorDomain Code=-50 "paramErr: error in user parameter list" (-50)
This error is mentioned again when Cypress creates a video of the incident:
- Started processing: Compressing to 32 CRF
2022-02-23 17:00:19.700 Cypress Helper[37571:416134] In -[NSApplication(NSQuietSafeQuit) _updateCanQuitQuietlyAndSafely], _LSSetApplicationInformationItem(NSCanQuitQuietlyAndSafely) returned error -50
- Finished processing: /Users/malte.wirz/Documents/iframes-cypress-issue/cypress/videos/iframe-github.js.mp4 (3 seconds)
I created a demo repository here. To reproduce, clone it, run yarn to install, and yarn cypress:run. The test does pass, but with the error mentioned above.
I assume that the error stems from accessing the nested iframes and I tested 5 different approaches so far, but to no avail. I especially made sure that the function getIframeBody waits until each iframe and the requested element is ready. The error also creates a video, but you can only see the successful run, the error message is not visible there.
Any help on how to debug this further is much appreciated.
describe('Testing Iframe within Iframes', () => {
it('Visits the iframe website and accesses the iframe within the iframe', () => {
const getIframeBody = (iframeSelector, elementSelectorInIframe) => {
return cy
.get(iframeSelector)
.its('0.contentDocument.body', {timeout: 30000})
.should((body) => {
expect(Cypress.$(body).has(elementSelectorInIframe).length).gt(0)
})
.then(cy.wrap)
}
// Visiting the page index.html and getting iframe A
cy.visit('index.html').contains('XHR in iframe')
getIframeBody('iframe[data-cy="bankid"]', 'iframe[src="https://tools.bankid.no/bankid-test/auth"]').as('iframeA')
cy.get('#iframeA').within(() => {
getIframeBody('iframe[src="https://tools.bankid.no/bankid-test/auth"]', 'iframe[src^="https://csfe.bankid.no/CentralServerFEJS"]').as('iframeB')
cy.get('#iframeB').within(() => {
getIframeBody('iframe[src^="https://csfe.bankid.no/CentralServerFEJS"]', 'input[type="tel"]').as('iframeC')
// Now we are in the right place and it finds the correct input element.
// However, normal cypress command .type() fails and we have to use library cypress-real-events,
// which provides an event firing system that works literally like in puppeteer
cy.get('#iframeC').find('input[type="tel"]').should('be.visible').realType('12345678912')
// But for the button below, this library now doesn't help anymore:
// "Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'."
// This was solved by using {scrollBehavior:false}.
cy.get('#iframeC').find('button[type="submit"]').should('be.visible').first().realClick({scrollBehavior:false})
})
})
})
})
I got some feedback that the above "ERROR:system_services.cc(34)" is not critical and does not cause flaky or unsuccessful tests, therefore there are no action points.
I have a problem using opencv.js when I want to detect aruco markers from my camera. Every time I try to use the method
let image = new cv.imread('img');
I get the following error:
TypeError: cv.Mat is not a constructor
at Object.matFromImageData (VM52998 opencv.js:55)
I tried to use this question to try and solve my issue. The solution from the question was to use async load, call onOpenCvReady() when the script is loaded, which will set a handler for onRuntimeInitialized event of cv. The handler should perform the necessary operations.
<script>
function onOpenCvReady() {
cv['onRuntimeInitialized']=()=>{
alert('OpenCV.js is ready.');
// do all operations
</script>
<script async src="<%= BASE_URL %>static/opencv.js" onload="onOpenCvReady();"></script>
However, when I tried to use the solution from the question I encoutered a problem:
the function onOpenCvReady() wasn't called at all.
In addition, I waited for more than 15 minutes (just to be sure) and then tried to use the line javascript let image = new cv.imread('img'); directly in console. Every move I made, and every step I took results in the same issue.
After going back to square 1, I had retried the most basic of solutions:
I just added this to my HTML page, instead of everything written here.
<script src="<%= BASE_URL %>static/opencv.js" id="opencvjs"></script>
This didn't directly worked, but after debugging some other areas of my code, I made sure that my page doesn't contain other errors (which are not related to this issue at all). For some reason I've yet to investigate and fully understand, having other errors while loading the opencv.js script has interrupted the loading process. Although it sounds unrelated, this had a huge effect on opencv commands.
The end result was magnificent:
let image = new cv.imread('img');
console.log(image);
OUTPUT:
Mat {$$: {…}}
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
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'));