click event for a link is not working for phantomjs - phantomjs

I am using nightwatchjs for end to end testing. My test passes for chrome, firefox, ie and edge but one of the test fails for phantomjs. click event for url seems to fail.
'do somethings' : function(browser) {
browser
.setValue('input[id=SearchInput]', '000')
.click('button[id=Button]')
.assert.containsText('label[id=nOutput]', '000')
.click('a[id=link]')// this click is not working
.pause(1000)
.assert.value('input[id=Input]', 'A')
.assert.value('input[id=InputB]', 'B')
//reset page
.click('button[id=__xmlview0--clearButton]')
.end()
},
Thanks for help.

Looks like a Selenium issue.
https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/5404
Selenium first gets the element's position, then sends a mouse click event. If the element moved between the time, the element will not be clicked.
I've encountered this too, my test case is trying to click A, but B gets clicked. Still trying to figure out a solution.
In another project I also encountered another reason. The page is responsive-ready, some elements are display:none when browser width is less than, say, 1000px. When nightwatch launches Chrome or Firefox, the browser window is full screensize, but phantomjs's default viewport size triggers the responsive condition. So Selenium cannot even find the element I want to click.

Related

How to scroll in selenium headless mode using Java?

Description
Because I don't yet have got any answer from mine post:
How to get all stocks from the specified URL in selenium headless mode?
I have to work on workaround to get progress on my work! Instead of trying to force an update on the site to get all stocks viewable (as described in my post) I will go to the end of page and then scroll up to force all stocks to get viewable (works fine when I do it manually).
All this MUST work in selenium headless mode!
Problem
I know how this can be implemented in selenium normal mode (not headless) but I can't get it to work in headless mode.
I think this line works both in normal and headless mode to go to the END of page:
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
The issue I'm struggeling with is how to scroll up or pageup from the end of the page. I guess something like this will work:
WebElement e = driver.findElement(By.xpath("element to be returned like Storskogen"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", e);
I can't fetch the element "e", I can't get it work (NoSuchElementException is thrown). I have copied the xpath or css from Chrome without result though. I'm not even sure this will work in headless mode.
Questions
how to fetch element "Storskogen"?
is "scrollIntoView" scrolling working in headless mode?
how can pageup be implemented and working in headless mode?
how can I verify scrolling in headless mode?
It's okay to not answer every question. I use Java for implemention.
Selenium headless window/display size by default is 800x600.
So if you have a lot on your webpage, then you may end up with horizontal, as well as vertical scroll bars on the headless browser. Therefore, dependent on your webpage, the element you are after may not be drawn, hence you have to scroll up and down for it to appear.
To get the best results of scrolling up and down, you want to maximise your browser window. As you want to operate in headless mode, the actual browser will not be active, thus driver.manage().window().maximize(); is not an option.
Do the following:
Update your browser driver with a specific window size that will ensure no horizontal scroll bars. I have used the following for my BrowserDriverFactory as I test with multiple browsers: driver.manage().window().setSize(new Dimension(1920, 1280)); also you could manage a specific browser driver i.e. chromedriver with options.addArguments("window-size=1920,1080");
Then use JavascriptExecutor, as you mentioned above:
Scroll down - ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
Scroll up - ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollTop);");

Selenium quasar app test element "click" issue

I have an app made with Quasar. I make e2e tests with python selenium using firefox. I log in and then would like to logout. To perform this I need as usually click on profile icon to show the menu and select Logout.
The issue is that whatever I tried the menu doesn't appear. The code looks as follows.
#pytest.mark.nondestructive
def test_must_login_and_logout_properly(logged_in_selenium, wait):
driver = logged_in_selenium
avatar = wait.until(EC.presence_of_element_located((By.XPATH, '//header//img[#alt="Profile image"]/ancestor::button/parent::span')))
# "natively" via selenium
ActionChains(driver).pause(1).move_to_element(avatar).click().perform()
# via javascript
driver.execute_script('document.evaluate(\'//header//img[#alt="Profile image"]/ancestor::button/parent::span\', document).iterateNext().dispatchEvent(new Event("click"))')
The above code doesn't work UNTIL I really click this element with the mouse. By putting time.sleep(10) at first line in test function and click. After that any method via avatar.click() or execute_script(...) works fine.
I also have an option to use PyAutoGUI to find the avatar on the screen and perform that click, but I don't like this variant.
-- UPDATE
I found out why it behaves like this, but still don't know how to work this around. Initially (after page load) click event handler is not attached to //header//img[#alt="Profile image"]/ancestor::button/parent::span element. It only appears after manual click in this area.
Any ideas?
You didn't share a link to this page, so I can only guess.
I would try to:
Wait for element visibility, not just existance.
Try to remove click from ActionChains action.
Add a short delay between moving to the element and click on it..
Still not sure, but possibly this will work
avatar = wait.until(EC.visibility_of_element_located((By.XPATH, '//header//img[#alt="Profile image"]/ancestor::button/parent::span')))
ActionChains(driver).pause(1).move_to_element(avatar).perform()
time.sleep(0.2)
avatar.click()
UPD
Try this:
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[#class='q-avatar']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Logout']"))).click()
Eventually it was necessary to click the element twice. Due to maybe Quasar implementation detail.
#pytest.mark.nondestructive
def test_must_login_and_logout_properly(logged_in_selenium, wait):
driver = logged_in_selenium
avatar = wait.until(EC.visibility_of_element_located((By.XPATH, '//header//img[#alt="Profile image"]/ancestor::button/parent::span')))
ActionChains(driver).pause(1).move_to_element(avatar).click().pause(0.5).click().perform()
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Logout']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[text()="You have logged out"]')))

Selenium WebDriver Explicit Wait intermittently not working

Good day everyone,
I need your help in this method. I have a web page that will have a loading screen UI when the page loads, and I'm waiting for it to finish before clicking a button.
Here is my code:
#Step("Go to Audit Inquiry Screen")
public void launchAuditInquiry(){
WebDriver webDriver = Driver.webDriver;
WebDriverWait wait = new WebDriverWait(webDriver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("loading-container")));
WebElement auditInquiryBtn = webDriver.findElement(By.linkText("Audit Inquiry"));
auditInquiryBtn.click();
}
My issue is sometimes, this code works fine. It will wait for the loading ui div to be invisible before clicking the button. But sometimes it will produce this error:
Error Message: org.openqa.selenium.WebDriverException: unknown error: Element <a class="module-item" href="/audit/inquiry">...</a> is not clickable at point (822, 436). Other element would receive the click: <div class="loading-container" style="display: flex; opacity: 0.899842;">...</div>
I tried adding another explicit wait before clicking the button to be sure, like this:
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("loading-container")));
WebElement auditInquiryBtn = webDriver.findElement(By.linkText("Audit Inquiry"));
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Audit Inquiry")));
auditInquiryBtn.click();
But it will sometime produce the same error above, and sometimes it will work fine.
I'm just confused on how to remediate the issue.
Thank you guys for the comments, especially this: Selenium Web Driver & Java. Element is not clickable at point (36, 72). Other element would receive the click
It was helpful, but some items there, I have already tried, but did not work as well. The part that I did check was one item there and also a comment here also which is to force a click:
new Actions(driver).moveToElement(auditInquiryBtn).click().perform();
But I'm having second thoughts on this because, a scenario may happen that when the loading container div is still overlaying the page, then I forced clicked the submit button, it will also produce another loading container div, and I'm not sure what will happen if there are two loading container div present.
Now, my solution on this is to adjust the sleep timer of the wait function:
WebDriverWait wait = new WebDriverWait(webDriver, 10, 2500L);
It now works because it gives the loader div time to generate before the first check of wait. 500 ms was a bit fast for the loader to render. I'm still testing this but if it didn't work, I might do the solution above.
Thanks again.
First thing to try is remove the invisibilityOfElementLocated wait and just use elementToBeClickable. I've never really trusted what Selenium considered "visible" and "invisible".
I've had issues in the past where the element to click on was completely off screen, so Selenium automatically scrolled until it was considered in the viewport. But because of a floating footer, it didn't scroll enough and was still behind the footer so could not be clicked on. It was still considered "visible" because it was in the viewport.
But, if you're sure, you can try forcing a click at a coordinate instead of an element.
new Actions(driver).moveToElement(auditInquiryBtn).click().perform();

How to send a click to hidden button?

I have a simple submit button on a page that I need to send a click for it but this button is at the bottom of the page and does not appear unless a user uses the browser vertical scroll bar to reach it !!
so when I use this C# code I get error element is not visible so how I can solve this problem ?
driver.FindElement(By.Id("submit")).Click();
You could scroll down using javascript. Something like this should do the work.
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
Selenium Webdriver implicitly scroll to the element, if it is visible. You can wait for the visibility of the element and then perform the click operation. In Java, we can wait for the visibility using following code:
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOfElementLocated(driver.findElement(By.id("submit"))));
In the above code, Webdriver will wait for 60 seconds, for the required element to become visible. If within 60 seconds, the element does not appear, then it will fail with timeout error. Once, the required element is visible, it can be clicked.
If it's not visible by you, it is not render by the browser used through your selenium driver.
I recommend you to simulate a scrolling to ensure your item will be visible, or do a simulation on a bigger resolution ?
Eventually you can consider switch to an headless driver...
I found the problem there are two elements in the page with id="submit" !! I used Name and now it work fine, thank to all.

Selenium evaluates DOM or Visible elements

I would like to understand how Selenium evaluates the page.
I have set of test to check elements on the page. Written with Nunit, Selenium and PhantomJS as Driver.
Page.Visit();
Page.FindElement(By.Id("testid").Text.Should().NotBeNull(); // PASS
Page.FindElement(By.Id("testid").Text.Should().NotBeEmpty(); // does NOT PASS
The test DOES NOT pass if the browser size is set to be very small:
driver.Manage().Window.Size = new Size(10,10);
Based on this test, it is confusing how PhantomJS evaluates the page. I always thought that it checks the DOM but seems like for element TEXT it evaluates based on visibility!
Although this surprised me too when I first discovered it, Selenium will only find elements visible in the viewport of the browser. For this reason, you will want to ensure at the start of your tests that your browser viewport is large enough to accommodate the content of your application.
Typically this can be done by maximizing the browser window. If you are using Windows, triggering the F11 key via Selenium should work.