SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
30.63k stars 8.18k forks source link

[🐛 Bug]: Impossible to accept geolocation in headless #11542

Closed gitfibcucumber closed 1 year ago

gitfibcucumber commented 1 year ago

What happened?

When using headless, it seems impossible to auto accept geo location (auto accept geo location seems to be the default in non headless)

ChromeDriver 108.0.5359.71 Chrome Version: 108.0.5359.124

With the attached code, if you comment out the line with "--headless" it works fine

How can we reproduce the issue?

package jsimple;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverService;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class StartMain {

    public static void main(String args[])
    {
        System.setProperty(
            "webdriver.chrome.driver",
            "/Users/Shared/chromedriver" // when running on local Mac
            );
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--no-sandbox");
    options.addArguments("--headless");  // comment out to try non headless (which works at the time of writting)

    Map<String, Object> prefs = new HashMap<String, Object>();
    prefs.put("profile.default_content_setting_values.geolocation", 1); // 1:allow 2:block (in non headless, the default is 1, in headless the default is 2)
    prefs.put("profile.managed_default_content_settings", 1);
    options.setExperimentalOption("prefs", prefs);
    DriverService.Builder<ChromeDriverService, ChromeDriverService.Builder> serviceBuilder = new ChromeDriverService.Builder();
    ChromeDriverService chromeDriverService = serviceBuilder.build();
    WebDriver driver = (WebDriver) new ChromeDriver(chromeDriverService, options);  

    driver.manage().window().maximize();
    driver.get("https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geolocation");
    String butXPath = "//button[contains(text(),'Try')]";
    String txtXPath = "//*[@id='demo' and contains(text(),'Lat')]";
    String iFramePath = "//*[@id='iframeResult']";
    String acceptPath = "//*[@id='accept-choices']";

    WebDriverWait w = new WebDriverWait(driver,Duration.ofMillis(15000));           
    w.until(ExpectedConditions.elementToBeClickable(By.xpath(acceptPath))).click(); 
    w.until(ExpectedConditions.presenceOfElementLocated (By.xpath(iFramePath)));
    driver.switchTo().frame(driver.findElement(By.xpath(iFramePath)));
    WebDriverWait w2 = new WebDriverWait(driver,Duration.ofMillis(15000));
    w2.until(ExpectedConditions.elementToBeClickable(By.xpath(butXPath))).click();
    w2.until(ExpectedConditions.presenceOfElementLocated (By.xpath(txtXPath)));
    WebElement txtEl = driver.findElement(By.xpath(txtXPath));
    Assert.assertEquals(true, txtEl.isDisplayed()); 
    driver.quit();

    // using maven 
    // mvn -X clean install 
    // mvn exec:java -Dexec.mainClass="jsimple.StartMain" -Dexec.classpathScope=test -Dexec.cleanupDaemonThreads=false -e   
    }
}

/* POM
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>jsimple</groupId>
  <artifactId>JSimple</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-devtools-v108</artifactId>
      <version>4.7.2</version>
    </dependency>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>4.7.2</version>
    </dependency>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-chrome-driver</artifactId>
       <version>4.7.2</version>
    </dependency>

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>2.13.3</version>
    </dependency>

  </dependencies>
</project>
*/

Relevant log output

The above test fails (it does not find the text as it never auto accepts the geolocation)

But if you comment out the headless, its passes fine

Operating System

Ubuntu (docker) and MaxOS

Selenium version

Java 4.7.2

What are the browser(s) and version(s) where you see this issue?

Chrome Version: 108.0.5359.124

What are the browser driver(s) and version(s) where you see this issue?

ChromeDriver 108.0.5359.71

Are you using Selenium Grid?

No response

github-actions[bot] commented 1 year ago

@gitfibcucumber, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

titusfortner commented 1 year ago

I'm writing a blog article about this, but in the meantime... It doesn't work because the headless browser is not the real browser. It has a bunch of the production stuff removed so it can run marginally faster.

Recommendations:

  1. You're using Linux, use the real production browser with XVFB
  2. If you can't use xvfb, use --headless=chrome which gives you the real production browser without the pixels painted

Beyond that, this is a Google issue and not a Selenium issue, so any changes to the headless mode would need to come from them.

github-actions[bot] commented 1 year ago

Hi, @gitfibcucumber. This issue has been determined to require fixes in ChromeDriver.

You can see if the feature is passing in the Web Platform Tests.

If it is something new, please create an issue with the ChromeDriver team. Feel free to comment the issues that you raise back in this issue. Thank you.