Wix Automation - Core

41
1 Wix Automation Core Roi Ashkenaz Oded Gefen

Transcript of Wix Automation - Core

Page 1: Wix Automation - Core

1

Wix AutomationCore

Roi AshkenaziOded Gefen

Page 2: Wix Automation - Core

2

Introduction

Page 3: Wix Automation - Core

3

IntroductionWix Editor

Page 4: Wix Automation - Core

4

Modeling DOM Elements

Page 5: Wix Automation - Core

5

Modeling DOM ElementsConcept• Each editor component will have its own class

(driver)• Driver represents a DOM node and its sub DOM

nodes• Class API will consist of methods returning sub

drivers of the component (building blocks)• Methods can return other complex drivers or simple

web elements

Page 6: Wix Automation - Core

6

Finding Elements

Page 7: Wix Automation - Core

7

Finding ElementsWix Editor

Page 8: Wix Automation - Core

8

Finding Elements - SeleniumWix Editor – Top Bar

public TopBar topBar() { return getElement().byClass("top-bar-editor", TopBar.class);}

Page 9: Wix Automation - Core

9

Finding Elements - SeleniumTopBar.java - Driver

public Button preview() { return getElement().byId("top-bar-preview", Button.class);}

public Button undo() { return getElement().byAttribute("automationId", "top-bar-undo",Button.class);}

Page 10: Wix Automation - Core

10

Finding Elements - JavaScript• Re-written completely using React.js• DOM nodes are less “rich” with information• Need stable selectors to find elements

Wix Editor – Revisited

Page 11: Wix Automation - Core

11

Finding Elements - JavaScriptTop Bar – React DOM

Page 12: Wix Automation - Core

12

Finding Elements - JavaScriptTopBar.java - Driver

public PageNavButton pageNavigation() { return getElement().byDisplayName("topBarPageNavButton", PageNavButton.class);}

Page 13: Wix Automation - Core

13

Finding Elements - Core

Page 14: Wix Automation - Core

14

By - CSSConcept• Predefined methods for getting elements with

different CSS selectors• Building the CSS selectors behind the scenes

(transparent for test code)

Page 15: Wix Automation - Core

15

By - CSSStandard examples• byId (#)• byClass (.)• byAttribute ([attribute=‘value’])• byCss(…)

Actual implementationwebDriver.findElement(By.cssSelector(selector));

Page 16: Wix Automation - Core

16

By - DisplayName Concept• Find elements using “decorations” visible only in React DOM• Use React Test Utilities (JavaScript)

public TopBar topBar() { return getElement().byDisplayName("topBar", TopBar.class);}

Page 17: Wix Automation - Core

17

By - DisplayNameActual implementation

Executing script located in client project:

- Pass display name string as script argument- Script returns a corresponding list of selenium WebElements - Usage of findAllInRenderedTree method from React Test

Utilities inside script implementation

domSelectors.getElementsByDisplayName(arguments[0]);

Page 18: Wix Automation - Core

18

By - DisplayNameActual implementationStream<WebElementProxy> searchElements(WebElementProxy root) {

List elements = (List) executeScript(...); return Stream.of(elements.toArray())

.filter(Objects::nonNull)

.map(WebElement.class::cast)

.map(WebElementProxy::new); }

WebElementProxy searchElement(WebElementProxy root) { return searchElements(root) .findFirst()

.orElseThrow(() -> new RuntimeException("Failed to get element " + this));

}

Page 19: Wix Automation - Core

19

Wrapping Native Selenium

Page 20: Wix Automation - Core

20

Wrapping Native SeleniumConceptWrapping useful selenium commands in our infrastructure

• Allows to change behavior of basic commands (e.g. wait after click)• Combine several actions together and create new

actions (drag and drop)• Add smart waits instead of sleep

Page 21: Wix Automation - Core

21

Wrapping WebDriverAPI• Navigation

Open URL in new window Close extra tabs Switch focus to last window Wait for number of windows to be (etc..)

• Logs Network Console errors

• Cookies Add Find Remove

Page 22: Wix Automation - Core

22

Wrapping WebDriverAPI• Navigation

Open URL in new window Close extra tabs Switch focus to last window Wait for number of windows to be (etc..)

• Logs Network Console errors

• Cookies Add Find Remove

Page 23: Wix Automation - Core

23

Wrapping WebDriverAPI – Navigation – Open URL in new window

public void openUrlInNewWindow(String url) { webDriver.executeScript("window.open()");

Object[] windowHandles = webDriver.getWindowHandles().toArray(); int numberOfWindows = windowHandles.size(); String targetWindowHandle = (String) windowHandles[numberOfWindows - 1]; webDriver.switchTo().window(targetWindowHandle); webDriver.manage().window().maximize();

webDriver.get(url); }

Page 24: Wix Automation - Core

24

Wrapping WebElementAPI

• Actions• Attributes• ElementWaitFor

Page 25: Wix Automation - Core

25

Wrapping WebElementAPI

• Actions• Attributes• ElementWaitFor

Page 26: Wix Automation - Core

26

Wrapping WebElementAPI – Actions

• dragAndDrop• clickAtOffset• doubleClick• mouseMoveToElement• setText• rightClick

Page 27: Wix Automation - Core

27

Wrapping WebElementAPI – Actions

• dragAndDrop• clickAtOffset• doubleClick• mouseMoveToElement• setText• rightClick

Page 28: Wix Automation - Core

28

Wrapping WebElementAPI – Actions – Drag and drop

public void dragAndDrop(int xOffset, int yOffset) { Actions actions = new Actions(webDriver); actions.clickAndHold(webElement) .moveByOffset(xOffset, yOffset) .release() .perform(); }

Page 29: Wix Automation - Core

29

Wrapping WebElementAPI

• Actions• Attributes• ElementWaitFor

Page 30: Wix Automation - Core

30

Wrapping WebElementAPI – Attributes

• getInnerHTML• getId• getCssClasses• getSize• getText• getPosition• isVisible• isEnabled

Page 31: Wix Automation - Core

31

Wrapping WebElementAPI – Attributes

• getInnerHTML• getId• getCssClasses• getSize• getText• getPosition• isVisible• isEnabled

Page 32: Wix Automation - Core

32

Wrapping WebElementAPI – Attributes – Get inner HTML

public String getInnerHTML() { String script = "return arguments[0].innerHTML;"; return (String) webDriver.executeScript(script, webElement);}

Page 33: Wix Automation - Core

33

Wrapping WebElementAPI

• Actions• Attributes• ElementWaitFor

Page 34: Wix Automation - Core

34

Wrapping WebElementAPI – ElementWaitFor

• attributeToBe• toExist• toBeDisplayed• textToBe• toContainsCssClass

Page 35: Wix Automation - Core

35

Wrapping WebElementAPI – ElementWaitFor

• attributeToBe• toExist• toBeDisplayed• textToBe• toContainsCssClass

Page 36: Wix Automation - Core

36

Wrapping WebElementAPI – ElementWaitFor – Wait for attribute to be

public void attributeToBe(String attribute, String value) {

BusyWait.create(TIMEOUT, POLLING_INTERVAL,

__ -> webElement.getAttribute(attribute).equals(value))

.execute(); }

Page 37: Wix Automation - Core

37

Wrapping WebElementAPI – ElementWaitFor – Wait for attribute to be

public void attributeToBe(String attribute, String value) {

BusyWait.create(TIMEOUT, POLLING_INTERVAL,

__ -> webElement.getAttribute(attribute).equals(value))

.execute(); }

topBar.waitFor().attributeToBe(”state”, ”noErrors”);

Page 38: Wix Automation - Core

38

Page 39: Wix Automation - Core

39

IframesConcept

• Each element “knows” if it’s inside an iframe • Each driver “knows” if it contains an iframe• Getting an element inside the iframe is done differently

Page 40: Wix Automation - Core

40

Iframes@Iframe class CKEditor extends Input {

public TextContainer textContainer() { return getIframeElement().byCss("h1", TextContainer.class); }

public Button bold() { return getElement().byId(”boldBtn", Button.class); }

}

Page 41: Wix Automation - Core

41