6. Selenium History
Selenium v1
● Uses JavaScript injection to emulate user interaction
Very flaky with modern apps
● Used in OTN Article (don’t do that)
Selenium v2 (aka WebDriver)
● Native events to drive browser
8. Page Objects
Martin Fowler:
“It should provide an interface that's easy to
program to and hides the underlying
widgetry in the window”
Source: martinfowler.com/bliki/PageObject.html
Also advocated by Selenium team
10. Basic JUnit Example
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
11. Basic JUnit Example
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
Page Object
12. Basic JUnit Example
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
ADF Component Object
13. Basic JUnit Example
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
Interact with
ADF Component
14. Basic JUnit Example
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
Test Assertion
15. Acquiring ADF Page Object
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
16. public class CalendarTest {
@ClassRule
public static WebDriverResource driver = new FirefoxDriverResource();
WebDriverResource starts (and stops) a web browser to run the tests
@ClassRule: invoke JUnit rule once per test class
@Rule: invoke JUnit rule for each test method
Acquiring ADF Page Object
17. public class CalendarTest {
@ClassRule
public static WebDriverResource driver = new WebDriverResource();
@Rule
public PageProvider<CalendarDemoPage> pages =
new PageProvider(CalendarDemoPage.class, PAGE_URL,
driver.getDriver());
PageProvider takes a WebDriver (browser) and knows how to navigate to a URL
and instantiate a Page Object
@Rule triggers provider for each test so we start fresh
Acquiring ADF Page Object
18. Acquiring ADF Component
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
20. Interacting with ADF Components
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
21. Interacting with ADF Components
import com.redheap.selenium.component.AdfComponent;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
public class AdfCalendar extends AdfComponent {
public void hoverActivityInView(int index) {
WebElement element = findAllActivitiesInView().get(index);
// move mouse to element and wait for ADF to detect hover
new Actions(getDriver()).moveToElement(element).pause(1000).perform();
waitForPpr();
}
}
Component class encapsulates interaction with HTML elements
Selenium Actions can interact with browser and mouse
AdfComponent.waitForPpr waits for any PPR and complete javascript processing
22. Interacting with ADF Components
@Test
public void testHover() {
CalendarDemoPage page = pages.goHome();
AdfCalendar calendar = page.findCalendar();
calendar.hoverActivityInView(0);
assertEquals("NOTE: This popup is for demo purposes only;...",
page.findPopupNote().getValue());
}
23. import com.redheap.selenium.component.AdfComponent;
public class AdfOutputText extends AdfComponent {
public Object getValue() {
return executeScript("var cmp=AdfPage.PAGE.findComponentByAbsoluteId(arguments[0]);"
+ "return cmp.getValue()",
getClientId());
}
}
CalendarDemoPage.findPopupNote returns AdfOutputText component
Component classes frequently use javascript to interact with components
AdfComponent base class offers protected executeScript method
Every component becomes a client component with
oracle.adf.view.rich.automation.ENABLED=true in web.xml
Interacting with ADF Components
26. Selenium Tools Component Classes
● Re-use a lot of logic that would otherwise live in Page Objects
● Rely heavily on ADF JavaScript API
● All extend from AdfComponent
○ click(), contextClick(), doubleClick()
○ dragAndDropTo(AdfComponent target)
○ findAdfComponent(String childId)
○ isDisabled(), isDisplayed()
○ scrollIntoView()
○ and a few more
27. Component Class Example: AdfTable
long getRowCount()
findAdfComponent(String child, int row)
scrollToRowIndex(int row)
discloseRowDetail(int row)
List<Integer> getDisclosedRows()
selectRow(int row)
selectToRow(int row)
selectAdditionalRow(int row)
... and all AdfComponent methods
29. Bounded Taskflow Recap
JUnit Test your taskflows
Use TaskFlow Tester for isolated tests - java.net/projects/adf-task-flow-tester
PerceptualDiffMatcher - bit.ly/pdiff
or look at more powerful Depicted at github.com/bslatkin/dpxdt
JaCoCo Code Coverage
JUnit Rule to dump execution data - bit.ly/jacoco-rule
Optional reporter to write html report - bit.ly/jacoco-report
Browser of choice: Firefox, PhantomJS or any other...