I've started to work with protractor + Jasmine for E2E testing.
The idea is to do an invalid operation and catch the exception:
expect(function () { return documentsPanel.clickUploadButtonError(); }).toThrow();
The documentsPanel is just a page object with multiple page actions. This is how I'm defining the method:
this.clickUploadButtonError = function () {
return uploadButton.click().thenCatch(function (err) {
throw('Cannot click upload button.');
});
};
The idea is for expect to pass by catching the error but my test still fails as uploadButton.click() throws a Selenium error:
Failed: unknown error: Element ... is not clickable at point (263, 131).
Any ideas on how can Jasmine catch the Selenium error?
You can provide an error callback explicitly:
return uploadButton.click().then(function success() {
console.log("Click was successful");
}, function failure(error) {
console.log("Click was unsuccessful");
console.log(error);
});
As a side note, if you are interested in tackling the "Element is not clickable" errors, please see this summary of the things to try.
Related
I am writing a simple WDIO selector with following statement. I was able to uniquely idenitfy it in browser. Not sure why WDIO was not able to set the value.
Given(/^I am on the login page$/, function () {
browser.url('https://secure-sandbox.modulrfinance.com/')
browser.maximizeWindow()
});
When(/^I enter password as \"([^\"]*)\"$/, function (password:string) {
//const txt_username = $('#username-inp')
//const txt_password = $('#password-inp')
$('#username-inp').setValue('')
$('#password-inp').setValue(password)
});
Then(/^I should see a flash message under username saying \"([^\"]*)\"$/, async function () {
const banner = await $('#.ng-star-inserted')
expect(banner).toHaveText('This field is required1')
});```
**error**
**[0-0] error: 'no such element',
[0-0] message: 'no such element: Unable to locate element: {"method":"css selector","selector":"#password-inp"}\n'** +
Seems like you are testing Single Page Application written in angular. You have to deal with the asynchronous behavior of Angular, by adding appropriate waits(Implicit, Explicit or Fluent waits).
Check this example.
I would like to be able to access all JS warnings and errors from the Browser Console during test runs. With the "-e" (skip JS errors) flag disabled, the test stops at the first error, so clearly it is looking for them. With this flag enabled, I would like to be able to see which errors (and ideally warnings) fired during test runs.
I've tried using the ClientFunction and window.onerror methods. I've also tried the -r 'reports' flag -- I only see TestCafe errors, not JS errors from the page under test. I've tried "Accessing Console Messages" from https://devexpress.github.io/testcafe/documentation/test-api/accessing-console-messages.html but this only gives messaging thrown by console.log, etc ("Note that this method returns only messages posted via the console.error, console.warn, console.log and console.info methods. Messages output by the browser (like when an unhandled exception occurs on the page) will not be returned.")
const installErrorHandler = ClientFunction(() => {
window.onerror = error => {
console.log("ERROR::::::");
console.log(error);
};
});
Over in the Clojure space, when using the Etaoin webdriver implementation (on Chrome or Phantom.js), at any point simply performing a
(get-logs driver)
returns
{:level :warning,
:message "1,2,3,4 anonymous (:1)",
:timestamp 1511449388366,
:source nil,
:datetime #inst "2017-11-23T15:03:08.366-00:00"}
....
....
Including any 'unhandled exceptions'.
Can I not do this in TestCafe?
Probably your example with window.onerror does not work because it executes later that error occurs. I suggest you extract the error handler into a separate *.js file and inject it using the new testcafe feature: Inject Scripts into Tested Pages.
Look at the following example:
script to inject (log-errors.js):
window.unhandledErrors = [];
window.onerror = (message, source, lineno, colno, error) => {
window.unhandledErrors.push({ message, source, lineno, colno, error });
}
test:
import { Selector } from 'testcafe';
fixture('Log errors')
.page('http://example.com')
.afterEach(async t => {
const errors = await t.eval(() => window.unhandledErrors);
console.log(errors);
});
test('test', async t => {
//...
});
Run tests by the following command:
testcafe chrome test.js -e --cs=./scripts/log-errors.js
Note that Script Injection feature is available since 1.4.0 version.
My scenario is to automate three sections in the same page and each section has a radio button, drop down etc..
After filling all the fields in each section I need to click Continue button and it takes a while to load.
I have successfully completed automating two sections, but when I click Continue button in the second section to navigate to the third. I am facing the below error
"TypeError: doneDeferred.fulfill is not a function"
I have understood that it may be synchronisation issue.So, I used
browser.ignoreSynchronisation=true;
Also, i tried to use
await browser.sleep(30000).then(function() {
console.log('Hello');
});
because I thought that since its taking a while to load its not inputting the values.But strangely, it doesn't go inside the function and print the console log message.
and this is the code in the debugger.js file:
validatePortAvailability_(port) {
if (this.debuggerValidated_) {
return selenium_webdriver_1.promise.when(false);
}
let doneDeferred = selenium_webdriver_1.promise.defer();
// Resolve doneDeferred if port is available.
let tester = net.connect({ port: port }, () => {
doneDeferred.reject('Port ' + port + ' is already in use. Please
specify ' +
'another port to debug.');
});
tester.once('error', (err) => {
if (err.code === 'ECONNREFUSED') {
tester
.once('close', () => {
doneDeferred.fulfill(true);
})
.end();
}
else {
doneDeferred.reject('Unexpected failure testing for port ' +
port + ': ' + JSON.stringify(err));
}
});
return doneDeferred.promise.then((firstTime) => {
this.debuggerValidated_ = true;
return firstTime;
}, (err) => {
console.error(err);
return process.exit(1);
});
Expected:I have pass values through sendkeys and drop down in that section and click continue button.
Actual:Its hanging in that screen and getting the above error.
I believe that the issue is with selenium webdriver promises.Can anyone help me with this?
I am still in the learning face with protractor cucumber framework.
I have a page with custom window.addEventListener("error", ...) logic. I'd like to test that it works, and the only real way to do so is to throw an error.
I tried this:
await browser.executeScript("throw new Error();");
...but Selenium itself saw the error and considered it an exception. Fine.
JavascriptError: Error
at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:550:15)
at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:542:13)
at Executor.execute (node_modules/selenium-webdriver/lib/http.js:468:26)
Next, tried doing that asynchronously:
await browser.executeScript(() => {
setTimeout(() => { throw new Error(); }, 1);
});
...but the page itself didn't notice the error (and yes, I've validated that throwing one in the dev tools triggers the expected handling).
Next, I tried using an async script that schedules an error and then the callback:
await browser.executeAsyncScript((callback) => {
setTimeout(
() => {
setTimeout(callback, 1);
throw new Error();
},
1);
});
...but the page itself still didn't notice the error.
Am I missing something here?
You can easily simulate that using below script
var errorElem = document.createElement("script");
errorElem.textContent = 'throw new Error("simulated error");'
document.body.append(errorElem);
This should be able to simulate the event
I am new to Selenium web drive. Trying to do some page automation and are using driver.wait functions to wait for a selector rendering first and then do some operations later.
Was wondering if Selenium has a way to pass in a timeout handler to manage timeout if the element is not showing up after x seconds.
Here's my code:
driver.wait(function () {
return driver.isElementPresent(webdriver.By.css('input[id="searchMap"]'));
}, 10000);
So after 10 secs if input[id="searchMap"] does not show up, Selenium script will end and Error is thrown.
I am looking for something like this:
driver.wait(function () {
return driver.isElementPresent(webdriver.By.css('input[id="searchMap"]'));
}, 10000, function fail(){
console.log("Time is up!");
});
Found a solution myself. Have to use catch for Selenium promise class.
http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/promise_exports_Promise.html
Here is my code:
driver.wait(function () {
return driver.isElementPresent(webdriver.By.css('div.info-page'));
}, 10000).catch(function(e){
console.log('Catching Error');
});