I'm using NightwatchJS to test a page with an embedded iFrame. The test opens the page, waits for the iframe to be present. All test steps work so far, but the iFrame's content tells me that the browser can not render embedded iframes.
Nightwatch Config (nightwatch.conf.js)
"chrome" : {
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true,
"nativeElements": true
}
},
Test Code
.waitForElementVisible('//iframe[#id = "botframe"]')
.element('xpath', '//iframe[#id = "botframe"]', (r) => console.log(r))
.assert.containsText('//iframe[#id = "botframe"]', 'Hello')
Output
✔ Element <//iframe[#id = "botframe"]> was visible after 61 milliseconds.
{ sessionId: '76685e966809e760c639d589ba318693',
status: 0,
value: { ELEMENT: '0.5426473824985356-1' } }
✖ Testing if element <//iframe[#id = "botframe"]> contains text: "Hallo" in 1000 ms. - expected "Hallo" but got: "<br><p>Da Ihr Browser keine eingebetteten Frames anzeigen kann...
You need to switch to the frame in order to check it’s contents, like
.frame(‘botframe’)
After you have finished checking the frame and want to return to your primary html content:
.frame(0)
// or
.frame(null)
//or
.frame()
Will return you to the original frame.
Related
I am automating a data capture form.
The first element of this form is an image file upload control & I'm uploading a 5KB image.
But after this step, the test executes the next step which is writing a text into a textbox & then it halts for nearly 30 seconds.
How to reduce this un-necessary wait?
test('Test 1', async t => {
await listingPage.uploadImage();
await listingPage.listAnItem();
..
Upload image code
async uploadImage() {
await t.setFilesToUpload(this.imageInput, ['../../uploads/photo02.jpg']);
}
** Data entry code block **
async listAnItem() {
await t
.typeText(Selector('#description'), this.DESCRIPTION) /* --> Application is slowing after this step */
.click(this.categorySelect)
.click(Selector('#react-select-2-option-0-0'))
.testcaferc.json file
{
"browsers": [ "chrome", "safari" ],
"remoteChromeVersion": "80",
"src": "specs",
"reporter": [
{
"name": "spec"
}
],
"speed": 1,
"debugOnFail": false,
"skipJsErrors": true,
"selectorTimeout": 20000,
"assertionTimeout": 20000,
"pageLoadTimeout": 8000
}
DOM Snippet of file-upload
<input aria-describedby="error__images" aria-label="Upload an image" tabindex="0" type="file" multiple="" accept="image/jpeg, image/png" data-testid="imageInput" class="ImageInputstyles__Input-sc-2l692w-7 aosWu">
The issue itself was not due to the Upload files control.
Issue was occuring, due to a drop-box, (after uploading file), which was dynamically updating another drop-box that had values populated dynamically based on the value selected in the first drop-down.
Rewriting the drop-down operation something like below resolved the issue:
async fillSubCategoryFields(catType = 'CAT_NAME') {
await t
.click(this.categorySelect, { timeout: 50 })
.click(Selector('.listingSelect__option').withText(catType));
}
I am injecting bunch of javascript code to a website by means of selenium webdriver (over chromedriver).
While the method i use works most of the time, it fails when an iframe is loaded or page is reloaded by website's javascript code.
I can trace the problem from the chromedriver's log.
For example:
[6.203][DEBUG]: DEVTOOLS EVENT Runtime.executionContextDestroyed {
"executionContextId": 1
}
[6.203][DEBUG]: DEVTOOLS EVENT Runtime.executionContextsCleared {
}
[6.203][DEBUG]: DEVTOOLS EVENT Runtime.executionContextCreated {
"context": {
"auxData": {
"frameId": "274.1",
"isDefault": true
},
"id": 5,
"name": "",
"origin": "https://<some url>"
}
}
When i see executionContextDestroyed i know that, most probably my injected scripts are destroyed too. I have tried bunch of options like switch_to.default_content() or switch_to.parent_frame but they didn't help, as there is nothing to do in case of reload but re-inject the scripts.
My question is, is there a way to hook into executionContextCreated events, so i can inject my scripts/functions into the context again and again.
I'm trying to write e2e tests using Nightwatch for a chrome extension. The extension inserts an iframe onto certain pages. I'm able to start up chrome with the extension but run into an error when I try to switch into the frame
Here is my test:
module.exports = {
'My test' : function (browser) {
browser
.url('https://myurl.com')
.waitForElementVisible('iframe[id=my_frame]', 5000)
.frame('my_frame')
.end();
}
};
Here is the error message:
INFO Response 200 POST /session/b747140552587912484ec27e0d91cd27/frame
(6ms) { sessionId: 'b747140552587912484ec27e0d91cd27', status: 8,
value: { message: 'no such frame: element is not a frame
(Session
info: chrome=58.0.3029.96)\n (Driver info: chromedriver=2.29.461591
(62ebf098771772160f391d75e589dc567915b233),platform=Windows NT
6.1.7601 SP1 x86_64)' } }
LOG → Completed command frame (10 ms)
I know the frame is there, because I can pause the test and inspect the page. Also nightwatch successfully finds the frame element in the waitForElementVisible command.
Here's the html
<iframe id="my_frame" src="chrome-extension://honkfenocfnhdbpakgenabnlnpgccadm/html/iframe/test.html" scrolling="false" style="width: 440px; transform: translateX(0px);"></iframe>
What am I doing wrong?
This looks like a chromium bug in case others run into this issue:
https://bugs.chromium.org/p/chromedriver/issues/detail?id=1777
Have you tried adding a .pause(1000) before switching to the frame?
I'm learning Protractor by making a very simple test:
describe('Tick Tack Toe game', function() {
it('marks positions as played', function() {
browser.ignoreSynchronization = true;
browser.get('file:///C:/Users/potero/angular/Angular_TickTackToe/ticktacktoe.html');
var p00 = element(by.id("p00"));
p00.click();
expect(p00.getText()).toEqual("X");
});
});
This test passed in Chrome almost effortlessly. But I also have to test on IE so I added the necessary lines to my protractor conf file which ended up like this:
exports.config = {
seleniumAddress : 'http://localhost:4444/wd/hub',
specs : [ '../specs/**/*.protractorspec.js' ],
multiCapabilities: [{
'browserName': 'internet explorer'
}, {
'browserName': 'chrome'
}]
};
Chrome kept passing the test but IE could not be launched due to its protected mode settings being different for every zone. I made them equal, which I read on this SO question. Then IE was launched but the test failed cause IE could not find the element with id p00 (check my spec above). By reading the error output on the console I saw the property of the IE selenium driver called "ignoreProtectedModeSettings" which was set to false. This got my attention so I reset the protected mode settings in IE and added a line to my protractor conf file, which ended up like this:
exports.config = {
seleniumAddress : 'http://localhost:4444/wd/hub',
specs : [ '../specs/**/*.protractorspec.js' ],
multiCapabilities: [{
'browserName': 'internet explorer',
'ignoreProtectedModeSettings': true
}, {
'browserName': 'chrome'
}]
};
And the IE test passed. Every time I ran it. So, why does a property that has to do with security settings allow me to find elements by id using Protractor selectors?
Background on Protected Mode
Internet Explorer’s Protected Mode is a security sandbox that relies upon the integrity level system in Windows. A process may have only one integrity level (IL), so if you navigate an IE instance between a Internet (Protected Mode, LowIL) and Intranet (non-Protected Mode, MediumIL) site, Internet Explorer must handle the navigation in a new process. In IE7 on Vista, this was very visible—a new browser window would open automatically. In IE8, with the introduction of Loosely-Coupled IE (LCIE), we can handle this more subtly.
You can find more information here: http://blogs.msdn.com/b/ieinternals/archive/2011/08/03/internet-explorer-automation-protected-mode-lcie-default-integrity-level-medium.aspx
Am new to protractor. I found some errors while automating the URL using protractor. And I can access the URL manually and does not find any issues. Please find the code mentioned below and kindly clarify my concern.
Screenshot of cmd while executing the code
exports.config={
specs: ['try.js'],
//seleniumArgs: ['-browserTimeout=60']
capabilities:{
'browserName':'chrome',
},
baseUrl:'',
allScriptsTimeout:3000,
//getPageTimeout:5000,
framework:'jasmine2',
jasmineNodeOpts: {
defaultTimeoutInterval:56000,
isVerbose: true,
}
}
spec: try.js
===========
describe('first try',function(){
var EW=protractor.ExpectedConditions;
beforeEach(function(done){
ignoreSynchronization=true;
browser.get('');
});
it('open PO',function(){
//clicking login button
var login=element(by.linkText('Login'));
browser.wait(EW.presenceOf(login),10000);
login.click();
//clicking open Po dashboard icon/link
var po=element(by.linkText('Open PO'));
browser.wait(EW.presenceOf(po),20000);
po.click();
//entering value 100 in the fiter field
var e=element.all(by.repeater('colFilter in col.filters')).get(00).element(by.tagName('input'));
browser.wait(EW.presenceOf(e),10000);
e.sendKeys(100);
//selecting the filterd values and printing it in console
element.all(by.repeater('col in colContainer.renderedColumns track by col.uid').column('Entity')).getText().then(console.log);
});
});
Make sure you have ng-app defined on all of your pages. Protractor requires it to run. If the page has redirects or just takes some time before it loads, try something like this:
browser.get(websiteUrl);
browser.wait(function () {
return browser.executeScript('return !!window.angular');
}, 10000, 'Error: Angular was not found on the page within ten seconds');
This will wait up to ten seconds for angular to load up, and fail if it is not there.