I'm unable to get my UI test to focus on a popup window. At this stage, I'd be happy to simply click PayBill, wait for the popup window (which loads instantly), then click Cancel.
The latest version of my code reads:
paybillButton.click();
browser.sleep(500);
browser.getAllWindowHandles().then(function (handles) {
newWindowHandle = handles[1];
browser.switchTo().window(newWindowHandle).then(function () {
cancelButton.click();
});
});
But it keeps failing between browser.switchTo() and .window(newWindowHandle).then ...
Error:
Failed: null value in entry: handle=null
WebDriverError: null value in entry: handle=null
at Object.checkLegacyResponse (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/error.js:505:15)
at parseHttpResponse (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/http.js:509:13)
at doSend.then.response (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/http.js:440:13)
at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: WebDriver.switchTo().window(undefined)
at thenableWebDriverProxy.schedule (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver.js:816:17)
at TargetLocator.window (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver.js:1755:25)
I've also tried the code below from Failed: null value in entry: name=null error while switching Popup window ...
function windowCount(count) {
return function () {
return browser.getAllWindowHandles().then(function (handles) {
return handles.length >= count;
});
};
};
browser.wait(windowCount(2), 10000);
browser.getAllWindowHandles().then(function (handles) {
browser.switchTo().window(handles[1]);
cancelButton.click();
});
But that's returning this error:
Failed: Wait timed out after 10002ms
TimeoutError: Wait timed out after 10002ms
at /usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2107:17
at ManagedPromise.invokeCallback_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:1366:14)
at TaskQueue.execute_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2970:14)
at TaskQueue.executeNext_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2953:27)
at asyncRun (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2813:27)
at /usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:676:7
at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: <anonymous wait>
at scheduleWait (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2094:20)
at ControlFlow.wait (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2408:12)
The switchTo method is a wrapper to the selenium-webdriver switchTo method. The switchTo method returns a TargetLocator object and the TargetLocator object does not have a window method. The correct way to do this is to use the frame method.
browser.getAllWindowHandles().then((handles) => {
let newWindowHandle = handles[1];
browser.switchTo().frame(newWindowHandle).then(() => {
cancelButton.click();
});
});
Related
I can successfully add screenshots to allure reports, but i get the following exception error:
error:
TypeError: Cannot read property 'currentStep' of undefined
at Allure.addAttachment (/Users//xxx/xxx/xxx/node_modules/allure-js-commons/index.js:86:45)
at Allure.createAttachment (/Users/xxx/xxx/xxx/node_modules/allure-js-commons/runtime.js:48:29)
at /Users/xxx/xxx/xxx/lib/class/class-name.js:30:20
at process._tickCallback (internal/process/next_tick.js:68:7)
class:
browser.takeScreenshot().then(function (png) {
allure.createAttachment(title, new Buffer(png, 'base64'));
}).catch((error: any) => console.log(error));
const allure = require('mocha-allure-reporter');
allure is a global identifier, injected by reporter to your code.
Add the following line to the top of your file to tell Typescript about it
declare const allure: any;
I think createAttachment requires a callback function and not a buffer being passed directly.
Can you try changing your code to reflect the following
browser.takeScreenshot().then(function (png) {
allure.createAttachment('Screenshot', function () {
return new Buffer(png, 'base64')
}, 'image/png')()
}).catch((error: any) => console.log(error));
I upgrade sails to the #^1.0.0 version and while I'm developing an API, I wanted to use a Service but the Sails document advice to use Helper now. And I don't realy use to work with the new way to discripe helper, build script or actions.
And all the try I have mad wasn't successful.
In the following exemple..
Here is my controller call:
var ob = await ails.helpers.testy('sayHello');
res.json({ob:ob});
helper
module.exports = {
friendlyName: 'Testy',
description: 'Testy something.',
inputs: {
bla: {
type: 'string'
}
},
exits: {
success: {
}
},
fn: async function (inputs, exits) {
console.log({blabla:inputs.bla})
if(!inputs.bla) return exits.error(new Error('text not found'));
var h = "Hello "+ inputs.bla;
// All done.
return exits.success(h);
}
};
I'm getting this error
error: A hook (`helpers`) failed to load!
error:
error: Attempted to `require('*-serv\api\helpers\testy.js')`, but an error occurred:
--
D:\*-serv\api\helpers\testy.js:28
fn: async function (inputs, exits) {
^^^^^^^^
SyntaxError: Unexpected token function.......
and if I remove the "async" and the "await" form the Controller, the ob object return null and I'm having this error
WARNING: A function that was initially called over 15 seconds
ago has still not actually been executed. Any chance the
source code is missing an "await"?
To assist you in hunting this down, here is a stack trace:
```
at Object.signup [as auth/signup] (D:\*-serv\api\controllers\AuthController.js:106:26)
The first guy from the comments is right.
After removing async from fn: async function (inputs, exists) {}; you need to setup sync: true which is false by default. It is described at helpers doc page at Synchronous helpers section.
So your code should look like this
module.exports = {
friendlyName: 'Testy',
description: 'Testy something.',
sync: true, // Here is essential part
inputs: {
bla: {
type: 'string'
}
},
exits: {
success: {
}
},
fn: function (inputs, exits) {
console.log({blabla:inputs.bla})
if(!inputs.bla) return exits.error(new Error('text not found'));
var h = "Hello "+ inputs.bla;
// All done.
return exits.success(h);
}
};
From the another side, you have a problem with async/await. The top most reason for this are
Not supported Node.js version - check that you current version support it
If you use sails-hook-babel or another Babel related solution, you may miss required plugin for async/await processing
We are using Protractor+Cucumber+Typescript combination.
Using protractor we are trying to login (Non angular OAuth) which redirects to application page (angular site). Following is our setup
feature file:
docsLogin.feature
Feature: Login to Docs
#TendukeLoginScenario
Scenario: Login to Docs application
Given I am on Tenduke login page
When Enter username and password
Then I click on Sign in button
Then I create a new folder
docsLoginPage.ts
import { $, element,by } from 'protractor';
export class TendukeLoginPageObject {
public usernameTextBox: any;
public passwordTextBox: any;
public signInButton: any;
public search: any;
public searchBox: any;
constructor() {
this.usernameTextBox = $("input[name='userName']");
this.passwordTextBox = $("input[name='password']");
this.signInButton = $("button[class='btn btn-primary']");
this.search = $("span[class='fa fa-search']");
this.searchBox = element(by.model('searchString'));
}
}
tenDukeLogin.ts
import { browser,element, by, } from 'protractor';
import { TendukeLoginPageObject } from '../pages/docsLoginPage';
import { defineSupportCode } from 'cucumber';
let chai = require('chai').use(require('chai-as-promised'));
let expect = chai.expect;
defineSupportCode(function ({ Given, When, Then }) {
let login: TendukeLoginPageObject = new TendukeLoginPageObject();
Given(/^I am on Tenduke login page$/, async () => {
browser.waitForAngularEnabled(false);
await expect(browser.getTitle()).to.eventually.equal('Sign in');
});
When(/^Enter username and password$/, async () => {
await login.usernameTextBox.sendKeys('abc#abc.com');
await login.passwordTextBox.sendKeys('12345');
});
Then(/^I click on Sign in button$/, async () => {
await (login.signInButton.click()).then(function(){
//browser.driver.wait((docs.plusIcon), 15000);
browser.wait((login.search).isPresent);
});
//await expect(browser.getTitle()).to.eventually.equal('Docs');
});
Then(/^I create a new folder$/, async () => {
//await browser.sleep(40000);
browser.waitForAngularEnabled();
await (login.search.click()).then(function(){
browser.wait((login.searchBox).isPresent);
});
});
})
Config.ts
import { browser, Config } from 'protractor';
export let config: Config = {
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://abc/content',
capabilities: {
browserName: 'chrome'
},
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
specs: [
'../../features/docsLogin.feature'
],
onPrepare: () => {
browser.ignoreSynchronization = true;
browser.manage().window().maximize();
},
cucumberOpts: {
compiler: "ts:ts-node/register",
strict: true,
format: ['pretty'],
require: ['../../stepdefinitions/*.ts', '../../support/*.ts'],
tags: '#TypeScriptScenario or #CucumberScenario or
#TendukeLoginScenario'
}
};
After clicking Sign in button browser closing immediately before
loading the application page.
We tried even adding some wait statement after Sign in but after timeout browser is closing. Not able to perform any action on Angular page after login.
protractor-typescript-cucumber#2.0.0 test E:\ProtractorTest\protractor-
cucumber-typescript
protractor typeScript/config/config.js
[18:10:52] I/launcher - Running 1 instances of WebDriver
[18:10:52] I/hosted - Using the selenium server at
http://127.0.0.1:4444/wd/hub
Feature: Login to Docs
#TendukeLoginScenario
Scenario: Login to Docs application
√ Given I am on Tenduke login page
√ When Enter username and password
(node:9096) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): TypeError: Cannot read property 'parentElementArrayFinder' of undefined
√ Then I click on Sign in button
x Then I create a new folder
Failures:
1) Scenario: Login to Docs application - features\docsLogin.feature:4
Step: Then I create a new folder - features\docsLogin.feature:8
Step Definition: stepdefinitions\tenDukeLogin.ts:29
Message:
NoSuchElementError: No element found using locator: By(css selector,
span[class='fa fa-search'])
at WebDriverError (E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\selenium-webdriver\lib\error.js:27:5)
at NoSuchElementError (E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\selenium-webdriver\lib\error.js:168:5)
at elementArrayFinder.getWebElements.then
(E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\protractor\lib\element.ts:851:17)
at process._tickCallback (internal/process/next_tick.js:109:7)Error
at ElementArrayFinder.applyAction_ (E:\ProtractorTest\protractor-
cucumber-typescript\node_modules\protractor\lib\element.ts:482:23)
at ElementArrayFinder.(anonymous function) [as click]
(E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\protractor\lib\element.ts:96:21)
at ElementFinder.(anonymous function) [as click]
(E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\protractor\lib\element.ts:873:14)
at E:\ProtractorTest\protractor-cucumber-
typescript\stepdefinitions\tenDukeLogin.ts:32:29
at next (native)
at E:\ProtractorTest\protractor-cucumber-
typescript\stepdefinitions\tenDukeLogin.ts:7:71
at __awaiter (E:\ProtractorTest\protractor-cucumber-typescript\stepdefinitions\tenDukeLogin.ts:3:12)
at World.Then (E:\ProtractorTest\protractor-cucumber-typescript\stepdefinitions\tenDukeLogin.ts:29:37)
1 scenario (1 failed)
4 steps (1 failed, 3 passed)
0m04.194s
Cucumber HTML report E:\ProtractorTest\protractor-cucumber-
typescript/reports/html/cucumber_reporter.html generated successfully.
[18:11:03] I/launcher - 0 instance(s) of WebDriver still running
[18:11:03] I/launcher - chrome #01 failed 1 test(s)
[18:11:03] I/launcher - overall: 1 failed spec(s)
[18:11:03] E/launcher - Process exited with error code 1
npm ERR! Test failed. See above for more details.
Could you explain me why do you use async over there?
Do you have any other steps with asycn which works?
Try to replace tenDukeLogin.ts with:
import {defineSupportCode} from 'cucumber';
import {browser, ExpectedConditions} from 'protractor';
import {TendukeLoginPageObject} from '../pages/docsLoginPage';
const chai = require('chai').use(require('chai-as-promised'));
const expect = chai.expect;
defineSupportCode(({ Given, When, Then }) => {
const login: TendukeLoginPageObject = new TendukeLoginPageObject();
Given(/^I am on Tenduke login page$/, () => {
browser.waitForAngularEnabled(false);
return expect(browser.getTitle()).to.eventually.equal('Sign in');
});
When(/^Enter username and password$/, () => {
login.usernameTextBox.sendKeys('abc#abc.com');
return login.passwordTextBox.sendKeys('12345');
});
Then(/^I click on Sign in button$/, () => {
return (login.signInButton.click()).then(() => {
return browser.wait(ExpectedConditions.visibilityOf(login.search), 5000);
});
});
Then(/^I create a new folder$/, () => {
browser.waitForAngularEnabled();
return (login.search.click()).then(() => {
return browser.wait(ExpectedConditions.visibilityOf(login.searchBox), 5000);
});
});
});
Drop me a line does it fix your issue.
I want to develop a framework where i keep all the locators at one place, in a json file say test.json. like this.
{
"yourName": "by.model('yourName')"
}
And I want to read this in specs as below.
var test = require('./test.json');
describe('angularjs homepage todo list', function() {
it('should add a todo', function() {
browser.get('https://angularjs.org');
var webElement = element(testtest.yourName);
webElement.sendKeys('write first protractor test');
});
});
but when i do this getting error as Failed: Invalid locator with following error trace.
Failures:
1) angularjs homepage todo list should add a todo
Message:
Failed: Invalid locator
Stack:
TypeError: Invalid locator
at Object.check [as checkedLocator] (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\by.js:267:9)
at WebDriver.findElements (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:919:18)
at C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:159:44
at ManagedPromise.invokeCallback_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14)
at TaskQueue.execute_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at asyncRun (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2775:27)
at C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:639:7
at process._tickCallback (internal/process/next_tick.js:103:7)Error
at ElementArrayFinder.applyAction_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:396:27)
at ElementArrayFinder._this.(anonymous function) [as sendKeys] (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:99:30)
at ElementFinder.(anonymous function) [as sendKeys] (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\built\element.js:730:22)
at Object.<anonymous> (E:\ui\TestTest\todo-spec.js:9:20)
at C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:94:23
at new ManagedPromise (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1082:7)
at controlFlowExecute (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:80:18)
at TaskQueue.execute_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at asyncRun (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2820:25)
From: Task: Run it("should add a todo") in control flow
at Object.<anonymous> (C:\Users\karunakaralchala\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:79:14)
From asynchronous test:
Error
at Suite.<anonymous> (E:\ui\TestTest\todo-spec.js:4:7)
at Object.<anonymous> (E:\ui\TestTest\todo-spec.js:3:5)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
Is there any better way to do this? or what should i need to make it work?
Probably not the direct answer to the question, but I think you are not attempting the problem in a traditional way and sort of partially reinventing the wheel.
Instead of keeping locators in a separate JSON structure, organize them into Page Objects - separate page objects (including element locators and methods to interact with a page) for separate pages or parts of pages.
This should work.
test.json
{
"siteURL": "https://angularjs.org",
"locators": {
"todoText": {
"model": "todoList.todoText"
}
}
}
spec.js
var test = require('./test.json');
describe('angularjs homepage todo list', function() {
it('should add a todo', function() {
browser.get(test.siteURL);
var webElement = element(by.model(test.locators.todoText.model));
webElement.sendKeys('write first protractor test');
});
});
One complete example using BDD Cucumber, json and pageobject model here. https://github.com/aluzardo/protractor-cucumber-tests/
One simple mistake in your approach.
The values from JSON are read as string and you are passing a string to element() and not a locator(not a by object)
var webElement = element(test.yourName); // Incorrect. test.yourName returns string
Change it way and voila ! You should be good. Use eval(). Refer here
var webElement = element(eval(test.yourName));
In my meteor.js application, I am trying to update a group's picture by using CollectionFS.
var groupimage = Images.insert(file);
Groups.update(groupId, {$set: { photo: groupimage }}, function(error) {
if (error) {
// display the error to the user
throwError(error.reason);
} else {
console.log('mongo document new');
console.log(Groups.findOne({_id:groupId}));
}
});
This does not work, it gives this error:
Exception in delivering result of invoking '/groups/update': ReferenceError: throwError is not defined
at http://localhost:3000/client/views/groups/editgroup/editgroupgeneral/editgr…dropzoneeditgroupgeneral.js?a1c6bb6d6c464c579ca4a82ca9f92775df17f5c5:39:21
at wrappedCallback (http://localhost:3000/packages/mongo-livedata.js?9213dc77ff40001575341a02827a8f1ed3200d98:531:9)
at null._callback (http://localhost:3000/packages/meteor.js?47d1d2b71177463dc159606cf930e44b9e3337f6:831:22)
at _.extend._maybeInvokeCallback (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:3802:12)
at _.extend.receiveResult (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:3822:10)
at _.extend._livedata_result (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:4831:9)
at onMessage (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:3667:12)
at http://localhost:3000/packages/livedata.js? 32d6f3870045baedecfa7c0d90861ead2810da37:2710:11
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
But when I insert instead of update, everything is working perfectly. This works.
var groupimage = Images.insert(file);
Groups.insert({
name: 'My Group',
photo: groupimage
});
What is the problem with my update? Thank you.
Edit
Exception in delivering result of invoking '/groups/update': Error
at http://localhost:3000/client/views/groups/editgroup/editgroupgeneral/editgr…dropzoneeditgroupgeneral.js?c24e8998d12b9aaa84912c2e87ec327e47277070:39:27
at wrappedCallback (http://localhost:3000/packages/mongo-livedata.js?9213dc77ff40001575341a02827a8f1ed3200d98:531:9)
at null._callback (http://localhost:3000/packages/meteor.js?47d1d2b71177463dc159606cf930e44b9e3337f6:831:22)
at _.extend._maybeInvokeCallback (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:3802:12)
at _.extend.receiveResult (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:3822:10)
at _.extend._livedata_result (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:4831:9)
at onMessage (http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:3667:12)
at http://localhost:3000/packages/livedata.js?32d6f3870045baedecfa7c0d90861ead2810da37:2710:11
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
Edit 2
errorClassdetails: undefinederror: 409errorType: "Meteor.Error"message: "MongoError: not okForStorage [409]"reason: "MongoError: not okForStorage"stack: (...)get stack: function () { [native code] }arguments: nullcaller: nulllength: 0name: ""prototype: Object__proto__: function Empty() {}<function scope>set stack: function () { [native code] }__proto__: Middle
You should maybe use Meteor's error method instead:
throw new Meteor.Error(500, error.reason);