42
ADF and Selenium Component Based Unit Testing

Automated Testing ADF with Selenium

Embed Size (px)

Citation preview

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