Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

93
Selenide Alternative in Python Introducing Selene

Transcript of Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Page 1: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide Alternative in PythonIntroducing Selene

Page 2: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Preface…

Page 3: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Alternative in PythonSelenideIntroducing Selene

Page 4: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide

Page 5: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide =

Page 6: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = ?

Page 7: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = … web automation tool

Page 8: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = … web automation tool

selenium wrapper

Page 9: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = … web automation tool

selenium wrapper

Page 10: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

Page 11: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

being also selenium wrapper

Page 12: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

?

Page 13: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

Page 14: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

Page 15: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser(it should be already

automated;)

Page 16: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

Page 17: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

waiting search

Page 18: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

waiting search

waiting asserts

Page 19: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

waiting search

waiting asserts

dynamic elements

Page 20: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selenide = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

waiting search

waiting asserts

dynamic elements

Page 21: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

? = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

waiting search

waiting asserts

dynamic elements

Page 22: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Selene = Effectiveweb test automation tool

=

tool to automate web UI tests logic

not browser

concise API

waiting search

waiting asserts

dynamic elements

Page 23: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

“UI Tests Logic” Automation with Selene

Page 24: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Page 25: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

class TestTodoMVC(BaseTest): def test_filter_active_tasks(self): # visit page # add "a" # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Page 26: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

# visit page # add "a" # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Page 27: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") # add "a" # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Page 28: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Page 29: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Concise API

Page 30: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Concise API

search element “short-cut”

Page 31: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Concise API

default conversion to “by css” locator

Page 32: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Concise API

with implicit clear()

Page 33: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Concise API

chainable methods

Page 34: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Dynamic Elements

search actually starts here

Page 35: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() # add "b" # add "c" # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Waiting Search

with implicit waiting for visibility

Page 36: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() # tasks should be "a", "b", "c" # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Page 37: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(exact_texts("a", "b", "c")) # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Waiting Asserts

Page 38: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(exact_texts("a", "b", "c")) # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

Waiting Asserts

aka “explicit waits”

Page 39: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) # toggle "b" # filter active # tasks should be "a", "c"

UI Tests Logic

handy conditions

Waiting Asserts

Page 40: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).find(".toggle").click() # filter active # tasks should be "a", "c"

UI Tests Logic

Concise API & Waiting Search

Page 41: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).find(".toggle").click() # filter active # tasks should be "a", "c"

UI Tests Logic

laconic inner collection search by text

Concise API & Waiting Search

Page 42: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).find(".toggle").click() # filter active # tasks should be "a", "c"

UI Tests Logic

laconic inner collection search by text

instead of bulky xpath locators

Concise API & Waiting Search

Page 43: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).find(".toggle").click() # filter active # tasks should be "a", "c"

UI Tests Logic

inner element search

Concise API & Waiting Search

Page 44: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).s(".toggle").click() # filter active # tasks should be "a", "c"

UI Tests Logic

handy alias

Concise API & Waiting Search

Page 45: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).s(".toggle").click() s(by_link_text("Active")).click() # tasks should be "a", "c"

UI Tests Logic

Page 46: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text("b")).s(".toggle").click() s(by_link_text("Active")).click() # tasks should be "a", "c"

UI Tests Logic

custom locators

Page 47: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text(“b")).s(".toggle").click() s(by_link_text("Active")).click() tasks.filterBy(visible).should_have(texts("a", "c"))

UI Tests Logic

Concise API & Waiting Asserts

Page 48: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text(“b")).s(".toggle").click() s(by_link_text("Active")).click() tasks.filterBy(visible).should_have(texts("a", "c"))

UI Tests Logic

Concise API & Waiting Asserts

filtering collection

Page 49: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

visit("https://todomvc4tasj.herokuapp.com/") s("#new-todo").set("a").press_enter() s("#new-todo").set("b").press_enter() s("#new-todo").set("c").press_enter() ss("#todo-list li").should_have(texts("a", "b", "c")) ss("#todo-list li").findBy(text(“b")).s(".toggle").click() s(by_link_text("Active")).click() tasks.filterBy(visible).should_have(texts("a", "c"))

UI Tests Logic

Page 50: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Page steps for even more readable code?

Page 51: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

#tasks.py

def visit(): tools.visit("https://todomvc4tasj.herokuapp.com/")

def add(*task_texts): for text in task_texts: s("#new-todo").set(text).press_enter() def filter_active(): s(by_link_text(”Active”)).click() def filter_completed(): s(by_link_text(”Completed”)).click()

Page 52: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

#tasks.py

tasks = ss("#todo-list>li") ...

def toggle(task_text): tasks.findBy(text(task_text)).find(".toggle").click() def should_be(*task_texts): tasks.filterBy(visible).should_have(texts(*task_texts))

Page 53: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

tasks = ss("#todo-list>li")...

Page 54: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

tasks = ss("#todo-list>li")...

Dynamic Elements

Page 55: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

tasks = ss("#todo-list>li")...

Dynamic Elements

possible because search does not start here

Page 56: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

tasks = ss("#todo-list>li")...

Dynamic Elements

possible because search does not start here

in fact, ss creates “lazy elements proxy” ;)

Page 57: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

class TestTodoMVC(BaseTest): def test_filter_tasks(self): tasks.visit() tasks.add("a", "b", "c") tasks.should_be("a", "b", "c") tasks.toggle("b") tasks.filter_active () tasks.should_be("a", "c") tasks.filter_completed () tasks.should_be("b")

Page 58: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Unfortunately still some “automating browser” low level

code needed for setup

Page 59: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

class TestTodoMVC(BaseTest): def test_filter_tasks(self): tasks.visit() tasks.add("a", "b", "c") tasks.should_be("a", "b", "c") tasks.toggle("b") tasks.filter_active () tasks.should_be("a", "c") tasks.filter_completed () tasks.should_be("b")

Page 60: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

@pytest.fixture(scope='class')def setup(request): set_driver(webdriver.Firefox()) def teardown(): get_driver().quit() request.addfinalizer(teardown)@pytest.mark.usefixtures("setup")class BaseTest(object): pass

Page 61: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Customisation

Page 62: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

config.app_host = "http://mydomain.com" ... visit("/subpage")

Page 63: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

s("#new-todo").should_be(enabled)

Default Timeouts Behaviour

will wait until 4 seconds

Page 64: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

s("#new-todo").should_be(enabled, timeout=10)

Custom

or

config.timeout = 10 ... s("#new-todo").should_be(enabled)

Page 65: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Widgets for even more structural OOP code?

Selene as htmlelements alternative ;)

Page 66: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 67: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 68: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 69: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 70: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 71: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Autocompletion as a bonus

Page 72: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 73: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Page 74: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

Inheriting all Selene element’s behaviour

Page 75: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

search inside self

Page 76: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Standalone custom element aka Widget

class Task(SElement): def delete(self): self.hover() self.s(".destroy").click()def test_custom_selement(): given_active("a", "b") Task("#todo-list>li:nth-child(1)").delete() ss("#todo-list>li").assure(texts("b"))

search inside self

Page 77: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

def test_custom_selements(): given_active("a", "b") page = TodoMVC() page.tasks.find(text("b")).toggle() page.clear_completed() page.tasks.assure(texts("a"))

PageObjects of “plural” Widgets: Usage

Page 78: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

def test_nested_custom_selements(): given_active("a", "b") page = TodoMVC() page.tasks.find(text("b")).toggle() page.clear_completed() page.tasks.assure(texts("a"))

PageObjects of “plural” Widgets: Usage

Page 79: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Autocompletion?

Page 80: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Autocompletion?

NO :’(

Page 81: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

PageObjects of “plural” Widgets: Implementation

class TodoMVC(object): def __init__(self): self.tasks = ss("#todo-list>li").of(self.Task) def clear_completed(self): s(“#clear-completed").click() class Task(SElement): def toggle(self): self.s(".toggle").click() return self

Page 82: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

PageObjects of “plural” Widgets: Implementation

class TodoMVC(object): def __init__(self): self.tasks = ss("#todo-list>li").of(self.Task) def clear_completed(self): s(“#clear-completed").click() class Task(SElement): def toggle(self): self.s(".toggle").click() return self

Page 83: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Just keep balance…

Page 84: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

class SelectList(SElement): def __init__(self, locator, context=RootSElement()): super(SelectList, self).__init__(locator, context) def set(self, value): self.assure(visible) Select(self.found).select_by_visible_text(value) return self

... s('[name="first_name"]').set('Iakiv')s('[name="last_name"]').set('Kramarenko') SelectList('#salutation').set('mr')

Good case for reusable Widget

Page 85: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

class SelectList(SElement): def __init__(self, locator, context=RootSElement()): super(SelectList, self).__init__(locator, context) def set(self, value): self.assure(visible) Select(self.found).select_by_visible_text(value) return self

... s('[name="first_name"]').set('Iakiv') s('[name="last_name"]').set('Kramarenko') SelectList('#salutation').set('mr')

Good case for reusable Widget

Page 86: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Doubtful…class TodoMVC(object): def __init__(self): self.tasks = ss("#todo-list>li").of(self.Task) class Task(SElement): def toggle(self): self.s(".toggle").click() return self

vs

tasks = ss("#todo-list>li")

def toggle(task_text): tasks.findBy(text(task_text)).find(".toggle").click()

Page 87: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Doubtful…

vs

tasks.toggle("b")

main.tasks.find(text("b")).toggle()

Page 88: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Keep It Simple Stupid!

Page 89: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

KISS Automation

Plain Pages over Pages of Nested Widgets

Page 90: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

KISS Automation

Plain Pages over Pages of Nested Widgets

Page Modules over PageObjects

Page 91: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

KISS Automation

Plain Pages over Pages of Nested Widgets

Page Modules over PageObjects

Automating UI tests logic over low level coding

Page 92: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

Q&A

Page 93: Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]

github.com/yashaka

github.com/yashaka/selene

[email protected]

@yashaka

Thank You