运行 Selenium 在无头 Chrome 中针对 Angular 应用程序进行测试

Run Selenium tests against an Angular application in headless Chrome

我正在尝试针对 Angular 应用程序创建 Selenium 测试。我希望这些测试 运行 在我的持续集成构建中,这需要 运行 在无头模式下对它们进行测试。我正在尝试使用无头 Chrome.

我创建了两个简单的 Selenium 测试。一个测试访问我的本地 Angular 应用程序,另一个访问 Google。当我 运行 他们使用 Chrome GUI 时,他们都 运行 完美,但是当我切换到 Chrome 无头时 Angular 测试失败。

我在 Angular 测试中打印出页面源代码,并且在使用 Chrome GUI 时所有 HTML 都正确呈现,但是当我切换到 headless 时,页面源代码只显示空 headbody 标签。

为什么会发生这种情况,我该如何解决?

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ExampleSeleniumTest {

    @LocalServerPort
    private int port;

    @Autowired
    private WebDriver driver;

    @Test // Always works
    public void testGoogle() {
        driver.get("http://www.google.com");
        WebElement element = driver.findElement(By.name("q"));
        element.sendKeys("Cheese!");
        element.submit();

        List<WebElement> findElements = driver.findElements(By.xpath("//*[@id='rso']//h3/a"));

        for (WebElement webElement : findElements) {
            System.out.println(webElement.getAttribute("href"));
        }
        Assert.assertTrue(findElements.size > 0);
    }


    @Test // Breaks in headless mode
    public void testLocalAngular() {
        driver.get("localhost:" + port);
        String pageSource = driver.getPageSource();
        // Page source empty in headless mode
        System.out.println(pageSource);
        String title = driver.findElement(By.className("mat-card-title")).getText();
        Assert.assertEquals("My Starter", title);
    }
} 

这些测试依赖于以下配置

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@ComponentScan(basePackageClasses = MyStarterApplication.class)
public class SeleniumConfig {

    @Value("${selenium.headless:#{true}}")
    private boolean headless;   

    @EventListener(classes = ApplicationReadyEvent.class)
    public void prepareDriver() {
        // Using https://github.com/bonigarcia/webdrivermanager
        ChromeDriverManager.getInstance().setup();
    }

    @Bean(destroyMethod = "quit")
    public WebDriver webDriver() {
        ChromeOptions options = new ChromeOptions();
        if (headless) {
            options.addArguments("headless");
            options.addArguments("window-size=1200x600");
        }
        WebDriver driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        return driver;
    }

}

问题是由以下原因引起的:

driver.get("localhost:" + port);

我需要指定协议。如果我使用:

,我的测试用例会起作用
driver.get("http://localhost:" + port);