0

I am using the latest chrome driver with selenium to test a web application hosted on Microsoft Azure.

The script starts by logging into the web application. An authentication window opens that requires the user to login through Azure and then press a, "Grant" button that will allow the web application to speak to a Therefore database to populate a few metadata fields.

This all works perfectly when headless mode is disabled. However, when headless mode is enabled it seems as though the, "Grant" button doesn't function. I am logging and taking screenshots during this process, which is how I know that the "Grant" button element is found and is being clicked. The button becomes highlighted when clicked, which is shown in the screenshot, but nothing happens and the authentication window times out in headless which kills the test.

Grant button found and highlighted as if clicked.

I have tried different clicking methods, but this made no difference as the element is found and is being clicked. I have also pressed the, "Sign in as a different user" button on the form to ensure that the .click() method is functioning as expected, which of course works. I tried to add longer wait times but to no avail.

I have also added the following Chromium driver options:

    ChromeOptions options = new ChromeOptions();
    options.addArguments("enable-automation");
    options.addArguments("--headless");
    options.addArguments("--start-maximized");
    options.addArguments("--window-size=1920,1080");
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-extensions");
    options.addArguments("--dns-prefetch-disable");
    options.addArguments("--disable-gpu");
    options.addArguments("--incognito");
    options.addArguments("--disable-web-security");
    options.addArguments("--allow-running-insecure-content");
    options.addArguments("--disable-dev-shm-usage");
    options.addArguments("--allow-insecure-localhost");
    options.addArguments("--disable-popup-blocking");
    options.setPageLoadStrategy(PageLoadStrategy.EAGER);

How I am clicking the element:

System.out.println("Grant permission...");
WebDriverWait wait = new WebDriverWait(driver, 30);
                    wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(),'Grant')]"))).click();

What baffles me is how this works seamlessly when headless is disabled but not when it's enabled. I'm wondering if this could be a Chrome driver issue? However I know that this is unlikely.

Any recommendations are appreciated, thanks.

Adding button HTML as requested:

<form method="POST">    
<p>Hello, Test</p>
<ul>

        <li class="text-left">Act with your access permissions</li>
        <li class="text-left">Allow continuous access while you are not online.</li>
</ul>
<p>
    <button type="submit" name="submit.Grant" value="Grant" class="btn btn-primary btn-block">Grant</button>
    <button type="submit" name="submit.Login" value="Sign in as different user" class="btn btn-outline-primary btn-block">Sign in as different user</button>
</p>
JumpingJacks
  • 257
  • 3
  • 18
  • [Already asked](https://stackoverflow.com/questions/47316810/unable-to-locate-elements-on-webpage-with-headless-chrome) – Carapace Sep 13 '22 at 10:11
  • @Carapace thanks for your response, however I am not getting a, "nosuchelement" exception. The element is found and the button is being pressed, it's just not functioning as it would when headless is disabled. – JumpingJacks Sep 13 '22 at 10:15
  • Did you read the answers? Tried the solutions? Did you try taking screenshot to understand what exactly is wrong for example? – Carapace Sep 13 '22 at 10:18
  • Yes carapace. I have already read this thread before. – JumpingJacks Sep 13 '22 at 10:31
  • Is that url publicly accessible (or can you create a dummy similar site) and can you share it? – Barry the Platipus Sep 13 '22 at 10:45
  • The locator seems fragile. Please post the relevant html of the element. To debug that step please take the screenshot before clicking on the element to know where you are. – KunduK Sep 13 '22 at 11:33
  • Thanks for your response. Locator will be updated. I am already taking screenshots before and after. First is taken before the click, which shows the button in its original state, and another after the click were the button is highlighted after the click event. HTML added. Kindly let me know if you need anything else. – JumpingJacks Sep 13 '22 at 11:41

2 Answers2

0

Try adding a wait. I mean use WebDriverWait to wait for the element to be clickable.
Something like:

WebDriverWait wait = new WebDriverWait(webDriver, 20);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div/div/div/div/div/div[2]/form/p[3]/button[1]"))).click();

Also you need to improve your locator.
Absolute XPaths are extremely fragile.

Prophet
  • 32,350
  • 22
  • 54
  • 79
  • But if it was a waiting issue it should send a NoSuchElement Exception, isn't? – Carapace Sep 13 '22 at 10:22
  • 1
    No. Possibly Selenium clicks on the element while it is not completely rendered. So, it exists, but clicking it simply does nothing. BTW this is why we should not use implicit waits – Prophet Sep 13 '22 at 10:25
  • Ah, right! It makes sense so, in headless mode it is faster and so it clicks the button earlier than the non-headless mode! Thank you – Carapace Sep 13 '22 at 10:31
  • Thanks for your responses! I've actually tried this solution before but unfortunately it didn't help. The button is definitely already rendered when clicking. Regarding xpath issue, yes there is an ID being added which I will make use of. – JumpingJacks Sep 13 '22 at 10:32
  • @Carapace This could be a reason, but as we see it is not... – Prophet Sep 13 '22 at 10:35
  • @JumpingJacks just for debugging. Try wait for the element clickable, then add some sleep of couple of seconds and only then click it? – Prophet Sep 13 '22 at 10:37
  • I have tried this but no luck unfortunately. Same result. – JumpingJacks Sep 13 '22 at 11:35
  • I'm sorry, currently I have no more ideas, but I hope you will finally find the solution. So, when you find it - please let me know what was the issue, it is interesting. – Prophet Sep 13 '22 at 11:38
  • 1
    I will, thank you very much for your responses Prophet! I appreciate your efforts. – JumpingJacks Sep 13 '22 at 11:42
  • 1
    You are more than welcome – Prophet Sep 13 '22 at 12:29
0

First, try to avoid very long CSS or Xpath expression. You can find the button you need to click on like this:

driver.findElement(By.xpath("//button[contains(text(),'Grant')]"));

This code is more readable. If the site will be changed and the element will be moved to another div or span - your code will not work if it relays on the structure of all the divs and spans.

Next, never just click on an element of hover over it in a Selenium test. First check if the element is clickable, then click:

WebElement term = driver.findElement(By.xpath("//button[contains(text(),'Grant')]"));
WebDriverWait wait = new WebDriverWait(webDriver, 20);
wait.until(ExpectedConditions.elementToBeClickable(term));
term.click();
Tal Angel
  • 1,301
  • 3
  • 29
  • 63
  • Thank you, I've implemented both of these already as recommended by other users. – JumpingJacks Sep 13 '22 at 12:45
  • @JumpingJacks For the StackOverFlow community it is important the every question will have an answer with code. Also, you can give a vote up for people who helped you, this is also very common in our community. – Tal Angel Sep 13 '22 at 13:00