WebDevice.IO is a lightweight Java-based framework for managing a collection of predefined WebDriver instances for use in browser automation test suites. The instances can be local, remote, and works well with Sauce Labs for driving desktop and mobile web devices.
<dependency>
<groupId>io.webdevice</groupId>
<artifactId>webdevice-spring-boot</artifactId>
<version>0.0.15</version>
</dependency>WebDevice works best with Spring. When used with Spring, the WebDevice runtime will manage the lifecycle of all
WbeDriver instances so that they will be automatically closed and quit.
If using plain Spring Test Framework, use the webdevice-spring-base artifact:
<dependency>
<groupId>io.webdevice</groupId>
<artifactId>webdevice-spring-base</artifactId>
<version>0.0.15</version>
</dependency>To activate the WebDevice runtime, apply the @EnableWebDevice annotation:
package com.someco.product.cucumber.steps;
import io.webdevice.device.WebDevice;
import io.webdevice.wiring.EnableWebDevice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
@EnableWebDevice
@ContextConfiguration(classes = TestConfiguration.class)
public class TestCase {
@Autowired
private WebDevice browser;
@Test
public void shouldDoSomething() {
browser.use("iPhone8");
browser.home();
browser.navigateTo(relativePath);
}
}As long as the webdevice-spring-boot artifact is on the classpath, the runtime will be activated automatically:
package com.someco.product.cucumber.steps;
import io.webdevice.device.WebDevice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = TestConfiguration.class)
public class TestSteps {
@Autowired
private WebDevice browser;
@Test
public void shouldDoSomething() {
browser.use("iPhone8");
browser.home();
browser.navigateTo(relativePath);
}
}package com.someco.product.cucumber.runner;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
glue = {"com.someco.product.cucumber.steps"},
features = {"src/test/resources/features"},
plugin = {"pretty"})
public class TestSuite {
}When using cucumber-spring, only one step definition is allowed to carry the context configuring
Spring annotation.
In the most common use case, WebDevice will be integrated into a test automation suite with an existing Spring
configuration. In this case, apply the @EnableWebDevice annotation to activate the runtime:
package com.someco.product.cucumber.steps;
import io.cucumber.java.en.Given;
import io.cucumber.spring.CucumberContextConfiguration;
import io.webdevice.device.WebDevice;
import io.webdevice.wiring.EnableWebDevice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@EnableWebDevice
@CucumberContextConfiguration
@SpringBootTest(classes = TestConfiguration.class)
public class TestSteps {
@Autowired
private WebDevice browser;
@Given("a {string} browser")
public void useBrowser(String name) {
browser.use(name);
}
@Given("a browser")
public void useBrowser() {
browser.useDefault();
}
@Given("I navigate home")
public void navigateHome() {
browser.home();
}
@Given("I navigate to {string}")
public void navigateTo(String relativePath) {
browser.navigateTo(relativePath);
}
}If the project utilizing WebDevice does not have an existing spring configuration and simply wants access
to the WebDevice instance, then the WebDeviceRuntime can be referenced directly:
package com.someco.product.cucumber.steps;
import io.cucumber.java.en.Given;
import io.cucumber.spring.CucumberContextConfiguration;
import io.webdevice.device.WebDevice;
import io.webdevice.wiring.WebDeviceRuntime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@CucumberContextConfiguration
@SpringBootTest(classes = WebDeviceRuntime.class)
public class TestSteps {
@Autowired
private WebDevice browser;
@Given("a {string} browser")
public void useBrowser(String name) {
browser.use(name);
}
@Given("a browser")
public void useBrowser() {
browser.useDefault();
}
@Given("I navigate home")
public void navigateHome() {
browser.home();
}
@Given("I navigate to {string}")
public void navigateTo(String relativePath) {
browser.navigateTo(relativePath);
}
}WebDevice.IO makes it simple to define various browser profiles for use in your automated tests. It supports
direct browser control as well as remote browser control. WebDevice definitions can be added to your
application.yaml file.
WebDriver.IO leverages the WebDriverManager library to set up the environment for direct browser control.
To indicate that a device definition is a direct WebDriver, the driver property must be defined:
webdevice:
devices:
DirectDevice:
driver: org.openqa.selenium.firefox.FirefoxDriver
aliases: Firefox, Local FirefoxRemoteWebDriver instances can be defined in various ways, primarily variation occurs when specifying
the capabilities of the driver. To indicate that a device definition is a RemoteWebDriver, the
remote-address property must be defined:
webdevice:
devices:
RemoteDevice:
remote-address: https://ondemand.saucelabs.com:443/wd/hubFor both direct and remote drivers, WebDevice.IO supports various means of specifying the Capabilities
of the device.
Browser specific Options can be used as the originating capabilities source, where capabilities
are merged into the Options instance:
webdevice:
devices:
FirefoxLatestMojave:
remote-address: https://ondemand.saucelabs.com:443/wd/hub
aliases: Firefox, Firefox Mojave
pooled: false
options: org.openqa.selenium.firefox.FirefoxOptions
capabilities:
username: ${saucelabs_username}
accessKey: ${saucelabs_accessKey}
extendedDebugging: true
platform: macOS 10.14
version: latestThe static factory methods on DesiredCapabilities (in this example DesiredCapabilities.safari())
can be used as the originating capabilities source, where capabilities are merged into the
DesiredCapabilities instance:
webdevice:
devices:
SafariLatestMojave:
remote-address: https://ondemand.saucelabs.com:443/wd/hub
pooled: false
desired: safari
capabilities:
username: ${saucelabs_username}
accessKey: ${saucelabs_accessKey}
extendedDebugging: true
platform: macOS 10.14
version: latestIt is also possible to construct a generic Capabilities instance directly:
webdevice:
devices:
Chrome59Windows10:
remote-address: https://ondemand.saucelabs.com:443/wd/hub
pooled: false
aliases: Chrome v59 Windows 10
capabilities:
username: ${saucelabs_username}
accessKey: ${saucelabs_accessKey}
browserName: Chrome
platform: Windows 10
version: "59.0"
extendedDebugging: trueDevices can take their capabilities from a Capabilities bean defined in the spring context:
webdevice:
devices:
RemoteDevice:
remote-address: https://ondemand.saucelabs.com:443/wd/hub
pooled: false
capabilities-ref: remoteDeviceCapabilitiesHere is an example definition adding sauce options:
webdevice:
devices:
ChromeLatestMojave:
remote-address: https://ondemand.saucelabs.com:443/wd/hub
pooled: false
options: org.openqa.selenium.chrome.ChromeOptions
capabilities:
w3c: true
platformName: macOS 10.14
browserVersion: latest
extra-capability: sauce:options
extra-options:
username: ${saucelabs_username}
accessKey: ${saucelabs_accessKey}
extendedDebugging: truewebdevice:
devices:
iPhone8:
remote-address: https://ondemand.saucelabs.com:443/wd/hub
aliases: iPhone 8
pooled: false
desired: iphone
capabilities:
username: ${saucelabs_username}
accessKey: ${saucelabs_accessKey}
extendedDebugging: true
appiumVersion: "1.13.0"
deviceName: iPhone 8
deviceOrientation: portrait
platformVersion: "12.2"
platformName: iOS
browserName: Safari
confidential:
- accessKey If the declarative abilities of WebDevice.IO are not sufficient, then simply provide your own DeviceProvider
implementation(s):
import io.webdevice.device.DeviceProvider;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static io.webdevice.device.Devices.remoteProvider;
import static org.openqa.selenium.remote.RemoteWebDriver.builder;
@Configuration
public class CustomProviderWiring {
@Bean
public DeviceProvider<RemoteWebDriver> myDevice() {
return remoteProvider("myDevice", this::customDriver);
}
private RemoteWebDriver customDriver() {
// Build up the custom RemoteWebDriver
return (RemoteWebDriver) builder()
.addMetadata("key", "value")
.build();
}
}Cross-browser Testing Platform and Open Source ❤️ provided by Sauce Labs