Reputation: 927
Hi I am having some trouble getting a basic protractor test to work.
My setup:
Protractor conf.json:
"use strict";
exports.config = {
specs: '../E2ETests/**/*.js',
chromeOnly: true,
getPageTimeout: 30000,
allScriptsTimeout: 30000
}
The test:
"use strict";
describe('When clicking should add stuff', function () {
var ptor;
beforeEach(function () {
browser.get('https://localhost/myApp');
ptor = protractor.getInstance();
});
it('add stuff', function () {
// If I comment this, the test pass.
element(by.id('add-stuff-button')).click();
// This does not matter fails on the line above..
expect(browser.getTitle()).toBeDefined();
});
});
The error:
UnknownError: unknown error: Element is not clickable at point (720, 881). Other element would receive the click: <div class="col-md-5 col-md-offset-5">...</div>
(Session info: chrome=37.0.2062.124)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.1 SP1 x86_64)
Thoughts
The chromedriver do find the button, because if I change the id it complains that no element is found. So I think the problem is that the button moves from its initial position. As the element(***) function should wait for angular to be done, I suspect that its the third party plugins that might interfere as they might not use angular api's fetching data etc. So angular think its done but then the third party plug populates and moves stuff around.
Any ideas what to do? If the third party plugs is the problem, can I somehow tell angular that third party stuff is going on and then later tell it when its done?
Thx Br Twd
Upvotes: 36
Views: 55600
Reputation: 8978
That means the element is not within the visible area. There are several ways to handle this:
await browser.executeScript('arguments[0].click();', $element.getWebElement());
await browser.executeScript(`arguments[0].scrollIntoView({block: "center"});`, $element.getWebElement());
await $element.click()
beforeAll(async () => await browser.driver
.manage()
.window()
.setSize(1920, 1080)
);
Upvotes: 0
Reputation: 4582
You can define the desired screen resolution through your protractor configuration file (e.g. protractor.conf.js
or config.js
) for consistent test behavior.
exports.config = {
specs: [
// ...
],
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: [
'--window-size=1600,900',
'--headless'
]
}
}
// ...
}
window-size
argument will launch Chrome with a 1600 by 900 window.headless
will launch headless Chrome, allowing you to have your tests run with the specified window size (1600 by 900) even if your screen resolution is lower than that.You may want to have two configurations, one for developers (without headless mode) who always have a high resolution screen and one for build servers (headless mode) where screen resolution is sometimes a mystery and could be lower than what your application / test is designed for. Protractor configuration file are javascript and can be extended to avoid code duplication.
Upvotes: 3
Reputation: 3797
Following worked fine for me:
browser.actions().mouseMove(element).click();
Edit: If above does not work try chaining perform() method too(I got this as an edit suggestion, I have not tested it but somebody could verify it and comment)
browser.actions().mouseMove(element).click().perform();
Upvotes: 25
Reputation: 1053
Had the same issue but was not related to the window size but had to wait for ngAnimation to end.
So I had to wait until the element was clickable with.
const msg = 'Waiting for animation timeout after 1s';
const EC = new protractor.ProtractorExpectedConditions();
await browser.wait(EC.elementToBeClickable(model.elements.button.checkCompliance), 1000, `${msg} panel`);
await model.elements.button.checkCompliance.click();
@note - I am using async/await node 8 feature, you could just as well convert this to regular Promises.
Also using ProtractorExpectedConditions
instead of ExpectedConditions
see documentation
Upvotes: 5
Reputation: 2239
This works better than specifying the window size, in case you test need to run on multiple displays.
browser.manage().window().maximize();
Upvotes: 2
Reputation: 3911
Note that this was sometime caused by a top navigation bar or bottom navigation bar / cookie warning bar covering the element. With angular 2, when clicking it scrolls until the element is only just on page. That means that when scrolling down to click something, if there is a bottom navigation, then this will obstruct the click. Similarly, when scrolling up it can be covered by the top navigation.
For now, to get around the scrolling up, I am using the following:
browser.refresh();
browser.driver.sleep(3000);
I made sure that I removed the bottom bar by clicking to close it before the test started.
Upvotes: 0
Reputation: 61
Other way, you can try this:
this.setScrollPage = function (element) {
function execScroll() {
return browser.executeScript('arguments[0].scrollIntoView()',
element.getWebElement())
}
browser.wait(execScroll, 5000);
element.click();
};
Upvotes: 1
Reputation: 4494
I fix this problem by using browser time sleep.
browser.driver.sleep(3000)
before giving click button
Upvotes: 3
Reputation: 129
Or simply use the Actions class:
browser.actions().mouseMove(elem).click().perform();
Upvotes: 12
Reputation: 35
From Gal Malgarit's answer,
You should set window size in your config file
onPrepare: function() {
browser.manage().window().setSize(1600, 800);
}
If it still doesn't work you should scroll to the element's location
browser.executeScript('window.scrollTo(720, 881);');
element(by.id('add-stuff-button')).click();
Upvotes: 0
Reputation: 1006
Maybe It is not applicable in your case, but I've encountered the same problem and based on Milena's answer I've been looking for another element obscuring my button (in my case, a dropdown menu in the top right of my screen).
It appears to be the Connected to Browser Sync notification message sent by browsersync, launched by Gulp. The message vanished after a short time, but after my onClick() call.
To remove the notification, in my gulpfile, I've added the notify: false param when initializing browsersync:
browserSync.init(files, {
server: {
baseDir: "dist",
index: "index.html"
},
notify: false
});
Upvotes: 4
Reputation: 944
You could also try turning off any debug tools you might be using. I was using Laravel and debugbar and had to set APP_DEBUG to false.
Upvotes: 0
Reputation: 113
I had the same error and purely adjusting the screen size did not fix it for me.
Upon further inspection it looked as though another element was obscuring the button, hence the Selenium test failed because the button was not (and could not be) clicked. Perhaps that's why adjusting the screen size fixes it for some?
What fixed mine was removing the other element (and later adjusting the positioning of it).
Upvotes: 2
Reputation: 5854
You should set window size in your config file
onPrepare: function() {
browser.manage().window().setSize(1600, 1000);
}
Upvotes: 35
Reputation: 795
This happens if the chrome window is too small, try to add inside the beforeEach
browser.driver.manage().window().setSize(1280, 1024);
Upvotes: 12