I am new to protractor and I am trying to figure out how to make the test/runner pause on failure. Ideally I would love to transition to the nodejs debugger but am open to any suggestion.
My use case is basically, when a test fails I would like to see what state the UI is in to help understand why the test failed.
Nick.
You can also add to the jasmine config, to stop when spec fails:
(same as how protractor-screenshot-reporter works)
for jasmine 1:
onPrepare: function () {
exports.config = {
onPrepare: function () {
jasmine.getEnv().addReporter({
reportSpecResults: function (spec) {
if (!spec.results().passed()) {
spec.results().items_.forEach(function (v) {
console.log(v.trace.stack);
});
browser.pause();
}
}
});
}
}
}
for jasmine2:
onPrepare: function () {
jasmine.getEnv().addReporter({
specDone: function (spec) {
if (spec.status === 'failed') {
console.dir(spec.failedExpectations.length);
console.log(spec.failedExpectations[0].message);
console.log(spec.failedExpectations[0].stack);
browser.pause();
}
}
});
}
then by typing "repl" in the console you switch to interactive mode, so you can try out the protractor commands.
You can put browser to sleep after or before your expect line to see what's going on.
browser.sleep(20000); // sleep 20 seconds
Update:
protractor now supports .pause() method.
browser.pause()
Read the docs here: https://angular.github.io/protractor/#/api?view=Protractor.prototype.pause
You should put browser.debugger() where you want your test to stop.
You have to have selenium standalone server running. You can start it using webdriver-manager start from command prompt. In your configuration file for protractor you have to have entry for selenium server pointing to that server like
seleniumAddress: 'http://localhost:4444/wd/hub', and entry for chromeOnly should be set to false. Debugging only works for chrome browser. Once you run you application it will drop into nodejs debugger. You have to press 'c' to continue. Once you debug statement is hit, you can do F12 to open debugger, and under console, you can use window.clientSideScripts to see what you have. I myself am at this point, but documentation for clientSideScripts is non-existant, so you can type the name of the function and it will give you the function definition. Then, you can try to figure out parameters it expects.
Related
I'm using Webdriver.io to download a file continuously
I tried the following code:
var webdriverio = require('webdriverio');
var options = {
desiredCapabilities: {
browserName: 'chrome'
// waitforTimeout: 1000000
}
};
webdriverio
.remote(options)
.init()
.url('https://xxx')
.setValue('#username', ‘xxx#gmail.com’)
.click('#login-submit')
.pause(1000)
.setValue('#password’,’12345’)
.click('#login-submit')
.getTitle().then(function(title){
console.log('Title was: ' + title);
})
.pause(20000)
.getUrl().then(function(url){
console.log('URL: ' + url);
})
.getTitle().then(function(title){
console.log('Title was: ' + title);
})
.click("a[href='/wiki/admin'] button.iwdh")
.getUrl().then(function (url) {
console.log('URL after settings ' + url);
})
.pause(3000)
.scroll('div.jsAtfH',0,1000)
.click("a[href='/wiki/plugins/servlet/ondemandbackup/admin']")
.pause(10000)
.click('//*[#id="backup"]/a')
//.pause(400000)
.end();
Note: The file size is 7GB and how long it will take to download is depend upon the network so instead of using pause() and timeout() is there any way to do it using webdriver.io or node.js ?
To begin with, your current task (waiting for a HUUUUGE file to download) is not a common use-case when it comes to Webdriver-based automation frameworks, WebdriverIO included. Such frameworks aren't meant to download massive files.
First off, you're confusing the waitforTimeout value with WebdriverIO test timeout. Your test is timing out before the .pause() ends.
Currently you're running your tests via the WebdriverIO test-runner. If you want to increase the test timeout, you have to use a different test framework (Mocha, Jasmine, or Cucumber) and set its timeout value to w/e you find appropriate. Going on, I recommend you use Mocha (coming from an ex-Cucumber guy).
You will have to install Mocha: npm install --save-dev wdio-mocha-framework and run your tests with it. Your test should look like this afterwards:
describe("Your Testsuite", function() {
it("\nYour Testcase\n", function() {
return browser
.url('https://xxx')
.setValue('#username', ‘xxx#gmail.com’)
.click('#login-submit')
// rest of the steps
.scroll('div.jsAtfH',0,1000)
.click("a[href='/wiki/plugins/servlet/ondemandbackup/admin']")
.pause(10000)
.click('//*[#id="backup"]/a')
)}
)}
Your config (wdio.conf.js) should contain the following:
framework: 'mocha',
mochaOpts: {
ui: 'bdd',
timeout: 99999999
}
As a side-note, I tried waiting a very long time (> 30 mins) using the above config and had no issues what-so-ever.
Let me know if this helps. Cheers!
If you click on a download button in your browser and you close your browser then your download will be also closed. If you are owning the website where you click on the download button then try to rewrite your code that you have a download able url. Then you can search for a module or way to download files from http url. If you are not the owner and you cant find a url in the href then you can maybe get the generated download url from the network section at your inspector.
Also I never heard that a browser gets closed after timeout? Maybe it comes from webdriver.io I never let my chrome so long open with webdriver.io
You can try to make a workaround use Intervall each 1 Minute as example and then use a webdriver.io command to don´t timeout.
I know it's very old question but I wanted to answer question from comment (and have no such possibility yet). But I will answer main question too.
When i am giving timeout in "wdio.conf.js" file it's not able to
downlaod file it's closing the session but by giving .pause(2000000)
in webdriver.io code it's able to download file of 7GB. What is the
use of timeout in "wdio.conf.js" file if it's kicking out the session
without downlaod?
So this timeout is related to elements state during the test run. So it "determines how long the instance should wait for that element to reach the state".
https://webdriver.io/docs/timeouts.html - this can help. But to answer the question too:
There are more many timeouts such test deals with. Like iamdanchiv wrote for this you should try using one of automatically supported frameworks like Mocha or Jasmine.
IMO right now the easiest way would to do the quick fresh setup using CLI provided by WDIO:
https://webdriver.io/docs/gettingstarted.html
Where you can just simply pick the additional framework you want to use. I would suggest using Jasmine and Chromedriver for this. Than in your wdio.conf.js you can change this part:
waitforTimeout: 10000,
jasmineNodeOpts: {
// Jasmine default timeout
defaultTimeoutInterval: 60000,
//
},
To something that works for you. Or you can use boilerplate projects from wdio page like this one:
https://webdriver.io/docs/boilerplate.html
But that's not all! Still you will have to create some method or function that checks for the file. So check where do you download the file or make it download where you want to and then create a method that uses some kind of wait:
https://webdriver.io/docs/api/browser/waitUntil.html
browser.waitUntil(condition, { timeout, timeoutMsg, interval })
So you can set the timeout either here or in wdio.conf in 'waitforTimeout'. Inside this method condition you can use node filesystem (https://nodejs.org/api/fs.html) to check the state of the file.
This can be helpful to get through waiting for file condition:
https://blog.kevinlamping.com/downloading-files-using-webdriverio/
What are the methods we can use to wait for an Angular site to be loaded in order to test it with protractor in order to avoid this error caused by jasmine : A Jasmine spec timed out. Resetting the WebDriver Control Flow ?
I'm able to make the login and go to home page that test is passed, but from the second test i have problems of jasmine.
I have configured this problem by adding this function into my config file :
onPrepare: function() {
return browser.getProcessedConfig().then(function(config) {
var browserName = config.capabilities.browserName;
browser.manage().timeouts().setScriptTimeout(60000);
});
});
You can use the browser object of Protractor to wait for angular.
As soon as you load your page add the following :
browser.waitForAngular();
This error means that your test took too much time and exceeded the default Jasmine spec timeout interval which is 30 seconds by default (It looks like you've configured the timeout to be 60 seconds). It can be configured in the jasmineNodeOpts object in your Protractor config:
jasmineNodeOpts: {defaultTimeoutInterval: timeout_in_millis},
The solution is usually use-case specific and it usually indicates there is an error in the test code. In order to fully understand what is going, we would need to see the code itself.
In your particular case, for starters, you should try moving the "ignore synchronization" and the browser.get() part into the beforeEach. Also, since you are turning the sync off, you need to wait for the element to be present on the page before interacting with it:
describe("my app", function () {
beforeEach(function () {
browser.ignoreSynchronization = true;
browser.get("...");
});
it("should make the login test", function () {
// ...
var EC = protractor.ExpectedConditions;
var username = element(by.model("credentials.username"));
browser.wait(EC.presenceOf(username), 10000);
username.sendKeys("RET02");
// ...
});
});
And, I am not sure if you really need to turn the synchronization off since this is an AngularJS page you are working with.
Can you wait for a url?
Let's assume that when you click on the login button your page is redirected to another url. So you can wait for the expected url. Example:
browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
// Dashboard is the loaded url after login (in this example)
return /Dashboard/.test(url);
});
}, 60000);
This code waits for the page browser.baseUrl/Dashboard to be loaded, for 60 seconds
I am testing a scenario where there are 3 checkboxes that are populated based on a service call and the response of http get.
The i am having is when i run the tests with protractor conf.js the drop downs have not yet been populated with the response from the http get response, and so when i try testing anything the browser stops and the tests fails.
Is there way so that protractor can wait before running tests on those drop downs to be filled?
conf.js:
// An example configuration file.
exports.config = {
//directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine 2 is recommended.
framework: 'jasmine2',
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['e2e/*.js'],
baseUrl: 'http://localhost:4000/',
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};
test file:
var select = element(by.model('make'));
console.log(select);
select.$('[value="acura"]').click();
this fails on the click event because when this test runs the select has no option elements as the select gets populated from a json http get response.
Thanks in advance!!
you can try using the method below; before calling the click.
browser.waitForAngular();
Use protractor's inbuilt wait() method using ExpectedConditions that expects the drop down to be filled. Here's how -
var select = element(by.model('make'));
browser.wait(protractor.ExpectedConditions.presenceOf(select.$('[value="acura"]')), 10000)
.then(function(){
select.$('[value="acura"]').click();
});
Hope it helps.
use browser.wait()-
browser.wait(function(){
return elementPresent.isPresent();
}).then(function(){
element.click();
})
I am running protractor to test angularjs app. All working fine, but when the browser window is spawned, it is in the background, so I have to cmd-tab to find it, and miss what happens at the start.
Is there any way I can programmatically bring the browser window to the foreground?
You can trigger an alert and immediately accept it. Put the following into onPrepare():
onPrepare: function () {
return browser.executeScript("alert('Test');").then(function () {
return browser.switchTo().alert().accept();
});
},
Or, as #LeoGalucci pointed out, take a screenshot:
onPrepare: function () {
return browser.takeScreenshot();
},
Note that return is important here - in this case, Protractor would not start executing tests until the promise returned from onPrepare() is resolved.
Both options worked for me.
Is it possible to leave the test browser windows open after Angular Protractor tests run? I have a tough test failing in FireFox and it'd be useful to access the state of the web page to see what's going on.
You can use Protractor debug/pause feature to pause the e2e run which will ultimately leave the browser open: more info here
To do so, add this line on your protractor test before the failing one
browser.pause();
There is also a very useful tool called elementor that you may want to take a look later on.
browser.pause no longer works with current Node v8.1.0, see here, but you could use browser.sleep(10000); to keep the browser open for e.g. 10 seconds
If you configured the test script to run using grunt, you could use the following code:
grunt.initConfig({
// ...
protractor: {
options: {
configFile: "protractor.conf.js",
keepAlive: true, // If false, the grunt process stops when the test fails.
noColor: false // If true, protractor will not use colors in its output.
},
run: {}
},
// ...
});
If you have Node 8+, bumped into issue "Error: Cannot find module '_debugger'" while attempting browser.pause solution from the accepted answer and you couldn't fix it using this github solution then you can workaround it as follows:
Install protractor as a module of the automation framework (i.e. without -g flag)
npm install protractor
Run webdriver-manager update for this protractor instance as well:
node ./node_modules/protractor/bin/webdriver-manager update
Where you have browser.pause(); in your code, replace it with debugger; statement
Run your code as follows:
node inspect ./node_modules/protractor/bin/protractor protractorConf.js
Where protractorConf.js is the config file of your protractor instance
If debugger waits for an input from you at the command line, just type cont and hit enter (to continue the execution)
super simple solution, that does exactly what's needed
The idea is that you don't really want to keep alive the session but rather pause it for a very long time when tests are done and be able to resume on-close procedures at any time
So just add this to your config.js
async onComplete() {
await browser.waitForAngularEnabled(false);
await browser.wait(
async () => {
let url = await browser.getCurrentUrl();
return url.includes('close/');
},
5 * 60 * 1000,
'Keep-alive timeout reached, closing the session...',
);
},
What the code does is, after all tests passed or failed, it waits until you type and submit close/ in browser's url field, or times out itself in 5 mins.
The reason await browser.waitForAngularEnabled(false); is needed here, because the browser opens an empty page when you type close/ which is non angular
You can even improve it and make it conditional, based on a parameter you pass to protractor config