Reputation: 12741
I'm attempting to create Selenium tests against an Angular application. I want these tests to run in my continuous integration builds, which necessitates running them in headless mode. I'm attempting to use headless Chrome.
I've created two simple Selenium tests. One test accesses my local Angular application, the other accesses Google. They both run perfectly when I run them using the Chrome GUI, but the Angular test fails when I switch to Chrome headless.
I print out the page source in the Angular test and all HTML is rendered correctly when using the Chrome GUI, but when I switch to headless the page source shows only empty head
and body
tags.
Why is this happening and how can I fix it?
@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);
}
}
These tests depend on the following configuration
@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;
}
}
Upvotes: 2
Views: 836
Reputation: 12741
The problem was caused by:
driver.get("localhost:" + port);
I needed to specify the protocol. My test case works if I use:
driver.get("http://localhost:" + port);
Upvotes: 1