运行 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 时,页面源代码只显示空 head
和 body
标签。
为什么会发生这种情况,我该如何解决?
@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);
我正在尝试针对 Angular 应用程序创建 Selenium 测试。我希望这些测试 运行 在我的持续集成构建中,这需要 运行 在无头模式下对它们进行测试。我正在尝试使用无头 Chrome.
我创建了两个简单的 Selenium 测试。一个测试访问我的本地 Angular 应用程序,另一个访问 Google。当我 运行 他们使用 Chrome GUI 时,他们都 运行 完美,但是当我切换到 Chrome 无头时 Angular 测试失败。
我在 Angular 测试中打印出页面源代码,并且在使用 Chrome GUI 时所有 HTML 都正确呈现,但是当我切换到 headless 时,页面源代码只显示空 head
和 body
标签。
为什么会发生这种情况,我该如何解决?
@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);