The Target Platform
feature of Selenium Foundation enables you to define a collection of "platforms" and associate each test with a specific platform. Prior to the start of each test, you have the chance to "activate" the platform. Beyond these general characteristics, how you define "platform" and "activation" is entirely up to you.
Examples:
- You're testing a responsive web application and want to implement tests for different screen dimensions - SMALL | MEDIUM | LARGE
- You're testing a localized web application and want to verify language-specific scenarios - EN_US | FR_CA | ES_MX
- You're testing a web application that supports role-based access control - GUEST | USER | ADMIN
The collection of platforms, what they mean, and how they're activated is only limited by your imagination.
The Target Platform
feature is supported for both TestNG and JUnit 4. The platform-related operations available for your implementation are identical for both. Whichever test framework you choose, the first step is to define your platform enumeration
.
To define the collection of platforms upon which your tests will run, start by extending the PlatformEnum
interface, defining the names of your platforms:
package com.nordstrom.automation.selenium.platform;
interface PhaseName extends PlatformEnum {
String PHASE1_NAME = "phase-1";
String PHASE2_NAME = "phase-2";
String PHASE3_NAME = "phase-3";
}
Next, declare a Java enumeration that implements this interface:
package com.nordstrom.automation.selenium.platform;
public enum Transition implements PhaseName {
PHASE1("green", PHASE1_NAME),
PHASE2("amber", PHASE2_NAME),
PHASE3("coral", PHASE3_NAME);
private String color;
private String name;
Transition(String color, String name) {
this.color = color;
this.name = name;
}
public String getColor() {
return color;
}
@Override
public String getName() {
return name;
}
@Override
public boolean matches(String contextPlatform) {
return name.equals(contextPlatform);
}
}
This basic example declares three platforms: PHASE1, PHASE2, and PHASE3. The PlatformEnum
interface defines two methods:
getName()
- Get the name of this platform constant.matches(String)
- Determine if the specified context platform matches this constant.
The only property of each platform constant that you're required to define is its name. In real-world implementations, though, you'll probably add related information as well. In this example, each constant defines an associated color. Here are other possibilities:
- Screen dimensions
- Language codes
- Account credentials
Add fields to your enumeration for these related items, and methods with which to retrieve them. The values are declared as arguments of each constant, with a constructor to assign these values to their respective fields. Note that declaring the platform names as interface constants allows them to be used to populate the enumeration and in declarations of the @TargetPlatform
annotation (see examples below). This avoids the need to hardcode platform names in the annotations or declare them twice in the enumeration.
As indicated previously, Selenium Foundation provides the opportunity to activate the target platform prior to the start of each test. To enable this automatic activation behavior, specify the initial page that your tests will interact with via the @InitialPage
annotation. By specifying the initial page, you can be certain that the driver is launched and has opened your target site, ready for action.
The examples shown below for TestNG and JUnit 4 both specify the initial page to open at the beginning of each test. Their platform activation methods store the name of the target platform in a session cookie. In your own implementation, perform whatever operations are needed to activate your platform (e.g. - change screen dimensions).
The easiest way to enable target platform support for TestNG tests is to subclass TestNgPlatformBase
. This class extends TestNgBase
and defines all of the elements required to activate the Target Platform
feature:
- Implementation of the
PlatformTargetable<P>
interface:TestNgPlatformBase(Class<P>)
constructorgetSubPath()
methodgetTargetPlatform()
methodactivatePlatform(WebDriver)
methodactivatePlatform(WebDriver, P)
stubgetValidPlatforms()
methodplatformFromString(String)
methodgetPlatformType()
method
- Attachment of
PlatformInterceptor
to the listener chain
This last element refers to the listener chain
, which is a core TestNG listener that must be activated to drive fundamental aspects of Selenium Foundation. Additional required elements are defined by the TestNgBase
class.
package com.nordstrom.automation.selenium.support;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import com.nordstrom.automation.selenium.annotations.InitialPage;
import com.nordstrom.automation.selenium.exceptions.PlatformActivationFailedException;
import com.nordstrom.automation.selenium.model.ExamplePage;
import com.nordstrom.automation.selenium.platform.Transition;
import com.nordstrom.automation.selenium.platform.TargetPlatform;
@InitialPage(ExamplePage.class)
public class TestNgPlatformTest extends TestNgPlatformBase<Transition> {
public TestNgPlatformTest() {
super(Transition.class);
}
@Test
public void testDefaultPlatform() {
assertTrue(getTargetPlatform().matches(Transition.PHASE1_NAME));
assertEquals(getTargetPlatform().getColor(), "green");
}
@Test
@TargetPlatform(Transition.PHASE2_NAME)
public void testPlatformTwo() {
assertTrue(getTargetPlatform().matches(Transition.PHASE2_NAME));
assertEquals(getTargetPlatform().getColor(), "amber");
}
@Override
public void activatePlatform(WebDriver driver, Transition platform)
throws PlatformActivationFailedException {
driver.manage().addCookie(new Cookie("color", platform.getColor()));
}
@Override
public Transition getDefaultPlatform() {
return Transition.PHASE1;
}
}
Given the intentionally generic nature of the Target Platform
feature, no direct reference is provided to the method for which platform activation is being performed. However, this is easily acquired:
...
@Override
public void activatePlatform(WebDriver driver, Transition platform)
throws PlatformActivationFailedException {
ITestResult result = Reporter.getCurrentTestResult();
if (result != null) {
ITestNgMethod method = result.getMethod();
...
}
}
...
The easiest way to enable target platform support for JUnit 4 tests is to subclass JUnitPlatformBase
. This class extends JUnitBase
and defines all of the elements required to activate the Target Platform
feature:
- Implementation of the
PlatformTargetable<P>
interface:JUnitPlatformBase(Class<P>)
constructorgetSubPath()
methodgetTargetPlatform()
methodactivatePlatform(WebDriver)
methodactivatePlatform(WebDriver, P)
stubgetValidPlatforms()
methodplatformFromString(String)
methodgetPlatformType()
method
- Instantiation of
TargetPlatformRule
Operations of the Target Platform
feature are driven by run watchers
, which must be connected to drive fundamental aspects of Selenium Foundation. These run watchers are in turn driven by test lifecycle events hooked into the core of JUnit 4 by the JUnit Foundation Java agent.
package com.nordstrom.automation.selenium.junit;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import com.nordstrom.automation.selenium.annotations.InitialPage;
import com.nordstrom.automation.selenium.exceptions.PlatformActivationFailedException;
import com.nordstrom.automation.selenium.model.ExamplePage;
import com.nordstrom.automation.selenium.platform.Transition;
import com.nordstrom.automation.selenium.platform.TargetPlatform;
@InitialPage(ExamplePage.class)
public class JUnitPlatformTest extends JUnitPlatformBase<Transition> {
public JUnitPlatformTest() {
super(Transition.class);
}
@Test
public void testDefaultPlatform() {
assertTrue(getTargetPlatform().matches(Transition.PHASE1_NAME));
assertEquals("green", getTargetPlatform().getColor());
}
@Test
@TargetPlatform(Transition.PHASE2_NAME)
public void testPlatformTwo() {
assertTrue(getTargetPlatform().matches(Transition.PHASE2_NAME));
assertEquals("amber", getTargetPlatform().getColor());
}
@Override
public void activatePlatform(WebDriver driver, Transition platform)
throws PlatformActivationFailedException {
driver.manage().addCookie(new Cookie("color", platform.getColor()));
}
@Override
public Transition getDefaultPlatform() {
return Transition.PHASE1;
}
}
Given the intentionally generic nature of the Target Platform
feature, no direct reference is provided to the method for which platform activation is being performed. However, this is easily acquired:
...
@Override
public void activatePlatform(WebDriver driver, Transition platform)
throws PlatformActivationFailedException {
AtomicTest atomicTest = LifecycleHooks.getAtomicTestOf(this);
FrameworkMethod method = atomicTest.getIdentity();
...
}
...
Written with StackEdit.