Top Banner
ADF and Selenium Component Based Unit Testing
42

Automated Testing ADF with Selenium

Feb 21, 2017

Download

Software

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Automated Testing ADF with Selenium

ADF and SeleniumComponent Based Unit Testing

Page 2: Automated Testing ADF with Selenium

About Us

Richard Olrichs

MN

www.olrichs.nl

@richardolrichs

Wilfred van der Deijl

The Future Group

www.redheap.com

@wilfreddeijl

Page 3: Automated Testing ADF with Selenium

AgendaDemo: Selenium

Plain Selenium Examples

Page Objects

Demo: ADF Selenium

ADF Selenium Tools

Demo: Testing Your Bounded Taskflows

Page 4: Automated Testing ADF with Selenium

Selenium 101 Demo

Page 5: Automated Testing ADF with Selenium

Selenium 101

public void simpleTest() {

WebDriver driver = new FirefoxDriver();

driver.get("http://google.com/?hl=en");

WebElement searchBox =

driver.findElement(name("q"));

searchBox.sendKeys("adf selenium");

searchBox.submit();

}

Page 6: Automated Testing ADF with Selenium

Selenium History

Selenium v1

● Uses JavaScript injection to emulate user interactionVery flaky with modern apps

● Used in OTN Article (don’t do that)

Selenium v2 (aka WebDriver)

● Native events to drive browser

Page 7: Automated Testing ADF with Selenium

Page Objects

Page 8: Automated Testing ADF with Selenium

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

Page 9: Automated Testing ADF with Selenium

ADF Selenium Tools

Page 10: Automated Testing ADF with Selenium

ADF Selenium Toolsgithub.com/wvanderdeijl/adf-selenium

Two JDev 12c Projects:

● SeleniumTools - Library JAR● RichClientDemoTest - Sample JUnit tests against ADF 12c component demo

Page 11: Automated Testing ADF with Selenium

ADF Selenium Demo

Page 12: Automated Testing ADF with Selenium

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 13: Automated Testing ADF with Selenium

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

Page 14: Automated Testing ADF with Selenium

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

Page 15: Automated Testing ADF with Selenium

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 withADF Component

Page 16: Automated Testing ADF with Selenium

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

Page 17: Automated Testing ADF with Selenium

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());

}

● How to start browser?● How to navigate to this page?

Page 18: Automated Testing ADF with Selenium

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 ObjectSeleniumTools

Selenium

CustomCode

Page 19: Automated Testing ADF with Selenium

public class CalendarTest {

@ClassRule

public static WebDriverResource driver = new FirefoxDriverResource();

@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 ObjectSeleniumTools

Selenium

CustomCode

Page 20: Automated Testing ADF with Selenium

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());

}

How does a Page Object locate components?

Page 21: Automated Testing ADF with Selenium

import com.redheap.selenium.component.AdfCalendar;

import com.redheap.selenium.page.Page;

public class CalendarDemoPage extends Page {

public AdfCalendar findCalendar() {

return findAdfComponent("dmoTpl:cal");

}

com.redheap.selenium.page.Page base class offers protected utility methodsfindAdfComponent uses (relative) JSF selectors

Acquiring ADF ComponentSeleniumTools

Selenium

CustomCode

Page 22: Automated Testing ADF with Selenium

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());

}

How did we implement component methods?

Page 23: Automated Testing ADF with Selenium

Interacting with ADF Componentsimport 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 elementsSelenium Actions can interact with browser and mouseAdfComponent.waitForPpr waits for any PPR and complete javascript processing

SeleniumTools

Selenium

CustomCode

Page 24: Automated Testing ADF with Selenium

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());

}

How did we implement component methods?

Page 25: Automated Testing ADF with Selenium

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 componentComponent classes frequently use javascript to interact with componentsAdfComponent base class offers protected executeScript methodEvery component becomes a client component withoracle.adf.view.rich.automation.ENABLED=true in web.xml

Interacting with ADF ComponentsSeleniumTools

Selenium

CustomCode

Page 26: Automated Testing ADF with Selenium

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

Page 27: Automated Testing ADF with Selenium

Component Class Example: AdfTablelong 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

Page 28: Automated Testing ADF with Selenium

Testing Your Bounded Taskflows

Page 29: Automated Testing ADF with Selenium

Bounded Taskflow RecapJUnit Test your taskflows

Use TaskFlow Tester for isolated tests - java.net/projects/adf-task-flow-tester

PerceptualDiffMatcher - bit.ly/pdiffor look at more powerful Depicted at github.com/bslatkin/dpxdt

JaCoCo Code CoverageJUnit Rule to dump execution data - bit.ly/jacoco-ruleOptional reporter to write html report - bit.ly/jacoco-report

Browser of choice: Firefox, PhantomJS or any other...

Page 30: Automated Testing ADF with Selenium
Page 31: Automated Testing ADF with Selenium

Resources

github.com/wvanderdeijl/adf-seleniumwww.seleniumhq.org - mostly v1 docsseleniumhq.github.io/docs/ - new v2 docs

Page 32: Automated Testing ADF with Selenium

Demo shots(reference material)

Page 33: Automated Testing ADF with Selenium

Example Test Start test in Taskflow Tester

Basic assertions

Compare screenshot

Page 34: Automated Testing ADF with Selenium

Taskflow running in Taskflow Tester

Page 35: Automated Testing ADF with Selenium

Validation Error triggered by test

Page 36: Automated Testing ADF with Selenium

JUnit Test Runner in JDeveloper

Page 37: Automated Testing ADF with Selenium

JaCoCo Code Coverage Report

Page 38: Automated Testing ADF with Selenium

JaCoCo Code Coverage shows this method wasn’t

covered in test

Not all paths tested

Page 39: Automated Testing ADF with Selenium

Screenshot Diff Assertion Violation

Tested application looks different during test compared to “known

good reference”

Page 40: Automated Testing ADF with Selenium

“Known good reference”

Page 41: Automated Testing ADF with Selenium

Actual screenshot during test

Page 42: Automated Testing ADF with Selenium

Diffs indicated