I develop some UI tests (running with Phantom.js configuration)
The tests themselves are very simple, for example (see some sample code below):
Browse a page - confirm the title expected is correct
Click a button/item to select an item from a list - confirm that the accurate item has been selected.
module.exports = {
'NodeCeller home page': function (test) {
test
.open('http://localhost:3000')
.assert.title().is('Node Cellar', 'Node Cellar is now open')
.done();
},
'NodeCeller Start Browsing Click': function (test) {
test
.click('a[href="#wines"]')
.assert.url('http://localhost:3000/#wines', 'Showing wines selection')
.done();
},
'NodeCellar Browse First Wine': function (test) {
test
.click('#content > div > ul > li > a')
.assert.text('legend','Wine Details', 'Showing Wines Details')
.done();
},
};
My question is this, I'd like to run the same set of tests in a loop for several times.
I have googled for Dalek.JS help and samples but I couldn't find any sample or article of how to do that.
Any help would be highly appreciated
Related
I can't understand why my emberjs test code runs so strange.
I wrote a test which should only select some html elements and give me number of them. This code works:
test('visiting /feedback/my', function(assert) {
visit('/feedback/my');
// if i remove this andThen test becomes failed
andThen(function(){
find(".feedback-item");
});
andThen(function(){
assert.equal(find(".feedback-item").length > 0, true, "There are more than 0 feedback");
});
click(".feedback-item:first a");
andThen(function() {
assert.equal(currentURL(), '/feedback/1', "New URL is /feedback/1");
});
});
But the same code but without (if i delete / comment it) this part andThen(function(){ find(".feedback-item")}); doesn't work. It throw's an exception: Element .feedback-item:first a not found.
I was wondering if anyone knew how to do the equivalent of 'keydown' and 'keyup' events with WebdriverIO? I currently have the following code:
// required pages
var LibraryPage = require('../../pageobjects/library.page.js');
describe('Delete Button', function(){
before(function (){
LibraryPage.open('/library/list/1/');
});
it('Delete button shows correct number of images', function (){
browser.keys('Ctrl');
LibraryPage.Image('asset1.jpg').click();
LibraryPage.Image('asset3.jpg').click();
LibraryPage.Image('asset5.jpg').click();
expect(LibraryPage.DeleteButton.getAttribute("title")).to.equal("Delete 3 assets");
});
});
// Library Page Object
DeleteButton: { get: function () { return browser.element('div[title^="TODO: Delete "]'); } },
Asset: { value: function(assetName) { return browser.element('tr*=' + assetName); } },
I want to hold the CTRL key while selecting images to multi-select.
What I have read indicates that the keys function should be sticky until it gets nulled out, but that’s not what I am experiencing.. Each item gets clicked without the CTRL button being held.
Using WebdriverIO v4 (synchronous JS).
Any help would be much appreciated, thanks!
I'm stuck in a problem. I have a set of end to end tests written with protractor.js and I made a little menu with inquire.js in which I'll select which tests I would like to run. The problem is, I really can't find any information on how to actually link those two projects together so the menu can call a test once selected. Here is a sample of a test and the menu I made:
This is my protractor test:
var session = require('../login.js');
describe('The customer view', function() {
var physicalPersonRegistration = {};
physicalPersonRegistration.loginTest = function() {
it('should Login', function() {
browser.ignoreSynchronization = true;
browser.get('http://localhost:8080/project');
session.username.sendKeys('admin');
session.password.sendKeys('admin');
session.submit.click();
browser.ignoreSynchronization = false;
});
};
//executing tests
physicalPersonRegistration.loginTest();
});
And this is my inquire.js menu:
var inquirer = require("inquirer");
var questions = [
{
type: "list",
name: "tests",
message: "Which test do you wish to run?",
choices: [
"Login Test",
"Run all Tests"
]
},
];
inquirer.prompt(questions, function(answers) {
console.log(answers);
});
The first thing to do is to determine what DOM elements you want to interact with. You can start by using the protractor element explorer. Use that to determine the kinds of locators to use. And then build your test around interacting with the browser.
My Protractor e2e tests are inconsistently passing and failing.
It seems this could be due to asynchronous javascript, as discussed here:
Protractor : How to wait for page complete after click a button?.
However, here it's mentioned that Protractor tests automatically execute sequentially / synchronously:
https://github.com/angular/protractor/issues/909
My test script:
describe('Login', function() {
var ptor;
beforeEach(function() {
browser.get('https://127.0.0.1:8443');
ptor = protractor.getInstance();
element(by.id('splash')).click();
browser.ignoreSynchronization = true; // <-- to proceed beyond splash screen
});
describe('with correct email and password', function() {
beforeEach(function() {
element(by.id('email')).sendKeys('admin#email.com');
element(by.id('password')).sendKeys('adminpassword');
element(by.id('loginButton')).click();
});
afterEach(function() {
ptor.findElement(by.id('logout')).then(function(elem) {
elem.click();
});
});
it('does not show alert', function() { // <-- sometimes passes, sometimes fails
expect(browser.isElementPresent(by.css('.alert-danger'))).toBe(false);
});
it('changes route to /admin', function() { // <-- sometimes passes, sometimes fails
expect(browser.getCurrentUrl()).toMatch(/\/admin/);
});
});
});
In the two tests above, either both tests will pass, or one/both of the tests will fail with these messages:
Failures:
1) Login with correct email and password does not show alert
Message:
NoSuchElementError: no such element
...
==== async task ====
WebDriver.findElement(By.id("logout"))
...
or
Failures:
1) Login with correct email and password changes route to /admin
Message:
NoSuchElementError: no such element
...
==== async task ====
WebDriver.findElement(By.id("logout"))
...
Thoughts / help much appreciated.
I was able to resolve the issue based on the following:
Avishay's answer here about adding ptor.waitForAngular():
No element found using locator: by.model() error
Changing browser.get to ptor.get, as in Harri Siirak's answer here:
Protractor times out waiting for sync with page when using $resource
juliemr's comment here about ignoreSynchronization being an instance variable, and changing browser.ignoreSynchronization=true to ptor.ignoreSynchronization=true:
https://github.com/angular/protractor/issues/49
glepretre's answer here about using .then():
Protractor : How to wait for page complete after click a button?
As mentioned by Nguyen Vu Hoang's comment to the original question, I am testing a pure Angular app with what I think is pure Protractor (no webdriver calls). I know ptor.ignoreSynchronization=true should not be required in this case, but for some reason, the tests are not proceeding at button click without this setting.
My new spec:
describe('Login', function() {
var ptor;
beforeEach(function() {
ptor = protractor.getInstance();
ptor.ignoreSynchronization = true;
ptor.waitForAngular();
ptor.get('https://127.0.0.1:8443');
ptor.findElement(by.id('splash')).then(function(elem) {
elem.click();
});
});
describe('with correct email and password', function() {
beforeEach(function() {
ptor.findElement(by.id('email')).then(function(elem) {
elem.sendKeys('admin#email.com');
});
ptor.findElement(by.id('password')).then(function(elem) {
elem.sendKeys('adminpassword');
});
ptor.findElement(by.id('loginButton')).then(function(elem) {
elem.click();
});
});
afterEach(function() {
ptor.findElement(by.id('logout')).then(function(elem) {
elem.click();
});
});
it('does not show alert', function() {
expect(ptor.isElementPresent(by.css('.alert-danger'))).toBe(false);
});
it('changes route to /admin', function() {
expect(ptor.getCurrentUrl()).toMatch(/\/admin/);
});
});
});
There is also an another technique to make your tests more stable: Explicit Waits and Expected Conditions (docs).
I've found using Expected Conditions especially useful when testing against non-angular pages or angular applications that have a lot of animations involved.
For example, you can wait for an element to be clickable before making a click:
var EC = protractor.ExpectedConditions;
var link = element(by.id("mylink"));
browser.wait(EC.elementToBeClickable(link), "10000", "The link is still not clickable");
link.click();
There are also other built-in Expected Conditions, such as:
presenseOf()
visibilityOf()
alertIsPresent()
textToBePresentInElementValue()
etc
And, it is easy to write a custom Expected Condition, example use case:
Testing link style changes
You can also combine Expected Conditions using and, or and not, e.g.:
var urlChanged = function() {
return browser.getCurrentUrl().then(function(url) {
return url != 'http://www.angularjs.org';
});
};
// condition to wait for url to change, title to contain 'foo', and $('abc') element to contain text 'bar'
var condition = EC.and(urlChanged, EC.titleContains('foo'), EC.textToBePresentInElement($('abc'), 'bar'));
$('navButton').click();
browser.wait(condition, 5000); //wait for condition to be true.
browser.ignoreSynchronization = true; has a global effect for all your tests. you may have to set it back to false, so protractor waits for angular to be finished rendering the page. e.g. in or before your second beforeEach function
So here another trouble. I have a script loading svg and waiting for it to appear which randomly fails. Sometimes phantom stay stuck loading svg (even with a waitTimeout at 2min, so the problem isn't here I think). script : http:// r.ccmbg.com/js.php?m=highchart=...
I could still load the page X times in a loop waiting for svg to appear, but I'd prefer another solution. If you have an idea, I'm all ears.
Simple example :
casper.test.begin('\n********* Navigation on directories : ***********', 8,{
setUp: function(test) {
//setLevel("normal");
},
tearDown: function(test) {
//getJSON();
},
test: function(test){
"use strict";
casper.start()
.thenOpen('http://www.linternaute.com/voyage/climat/paris/ville-75056/2013-2008')
.waitForResource(/m=highcharts&/, function(){
this.waitForSelector('svg',function(){
this.test.assertExists("tspan");
});
})
.waitForUrl(/2008/, function(){
this.test.assertSelectorHasText("h2", "maximales");
this.test.assertSelectorHasText("h2", "minimales");
this.test.assertSelectorHasText("h2", "Paris");
this.test.assertSelectorHasText("h2", "Le soleil");
this.test.assertSelectorHasText("h2", "La pluie");
this.test.assertExists("div.marB20");
this.test.assertNotEquals(this.fetchText("div.marB20 > table > thead > tr > th"), " ", "Table first data not empty");
})
.run(function() {
this.test.comment('--- Done ---\n');
test.done();
});
}
});
Well, when I don't know the script called or the API used (so I can't debug myself), I just check the ressource now.
this.waitForResource(/js\.php\?m=highcharts&v/, function(){
this.test.pass("ressource received (js -> API highcharts)");
});
Don't forget this event to get back page document error :
casper.on("page.error", function(msg, trace) {
this.echo("Page Error: " + msg, "ERROR");
});