Oz is a behavioral web-ui testing framework developed to reduce test maintenance by using a predictive model rather than a scriptive model when writing tests.
Apache License 2.0
23
stars
7
forks
source link
[Feature Evaluation] Wrapping defined driver elements #141
Okay, as per the discussion @greenarrowdb and I had in discord the other day, i'm going to document my thoughts here. Pardon the conscious stream of thought, it's just how things tend to live in my head.
I'm finding the hard ban on watir elements in the page models to be a lot more limiting than i originally thought and i'm finding that it causes me to have to..
A. Reinvent the wheel
B. Write somewhat confusing code
Some examples might be a bit more telling here... Say i wanted to define a navigation bar for github. I'm not going to use the best selectors here because they wouldn't be available in the model i'm testing against.
If i wanted to get a given nav link in watir
class Github
class BasePage
@header_bar = @browser.a(class: 'header-logo-invertocat').parent.parent.parent.parent
@nav_links = @header_bar.links
def visit(option)
nav_link(option).click
end
def nav_link(option)
@nav_links.find{|it| it.text =~ /option/i}
end
end
end
Oz's paradigm for this gets a lot less readable really quickly, one reason being that i'd have to use an xpath to find that header bar, another being that i end up with a lot of replication, and i have to statically define each element, since post processing availability is currently very limited being that the page models don't allow me to easily request a sub element... anonymously for lack of a better word.
class Github
class BasePage < CorePage
def create_common_elements
@header_bar = add_element(:header_bar, element_type: :header, CoreElement, xpath: '//a[@class="header-logo-invertocat"]/../../../header') #this may not be exactly correct
@header_nav_links = []
@header_nav_links << add_link(:header_bar_pull_requests, parent: @header_bar, xpath: '//a[1]')
@header_nav_links << add_link(:header_bar_issues, parent: @header_bar, xpath: '//a[2]')
@header_nav_links << add_link(:header_bar_marketplace, parent: @header_bar, xpath: '//a[3]')
@header_nav_links << add_link(:header_bar_explore, parent: @header_bar, xpath: '//a[4]')
end
def visit(option)
click_on nav_link(option)
end
def nav_link(option)
@header_nav_links.find{|it| it[:name].to_s =~ /option.gsub('_','')/i}
end
end
end
Granted, I understand that visit as a method isn't something that's typically used on the external page api in this case (i'm using it to ease defining a route, which i think should fit within the expected behavior). The Oz way just feels... really clunky to me as is.
With all of this background i can finally get to my point i think.
I don't necessarily fully believe that driver elements don't have their place in a given page model. They would allow for much easier definition of structural objects on the page (things that are only really used to navigate the dom and find other elements more easily) and let us get to the stuff we actually care about validating much more easily. Something like the below example would feel pretty nice to me.
class Github
class BasePage < CorePage
add_route('Github::PullRequests', [:click_on, :pull_request_link])
def create_elements
@header_bar = browser.a(class: 'header-logo-invertocat').parent.parent.parent.parent
add_element(:header_bar, driver_element: @header_bar)
create_nav_links
end
def create_nav_links
@header_bar.links.each do |link_element|
add_link(link_element.text.to_field_name, driver_element: link_element)
end
end
end
end
This has a few benefits, two big ones being
reduces maintenance and repetition on the page model quite a bit.
think if a new link gets added to the nav bar, now all we have to do is define a new route for it at
the top of the page
still maintains the existing api where we get easily defined checks on elements
Some of the immediate cons I can think of though.
increases coupling to whatever driver you're using to develop
might get kinda brittle (what happens with those symbol links on the right side of githubs header?)
Okay, as per the discussion @greenarrowdb and I had in discord the other day, i'm going to document my thoughts here. Pardon the conscious stream of thought, it's just how things tend to live in my head.
I'm finding the hard ban on watir elements in the page models to be a lot more limiting than i originally thought and i'm finding that it causes me to have to.. A. Reinvent the wheel B. Write somewhat confusing code
Some examples might be a bit more telling here... Say i wanted to define a navigation bar for github. I'm not going to use the best selectors here because they wouldn't be available in the model i'm testing against. If i wanted to get a given nav link in watir
Oz's paradigm for this gets a lot less readable really quickly, one reason being that i'd have to use an xpath to find that header bar, another being that i end up with a lot of replication, and i have to statically define each element, since post processing availability is currently very limited being that the page models don't allow me to easily request a sub element... anonymously for lack of a better word.
Granted, I understand that visit as a method isn't something that's typically used on the external page api in this case (i'm using it to ease defining a route, which i think should fit within the expected behavior). The Oz way just feels... really clunky to me as is.
With all of this background i can finally get to my point i think. I don't necessarily fully believe that driver elements don't have their place in a given page model. They would allow for much easier definition of structural objects on the page (things that are only really used to navigate the dom and find other elements more easily) and let us get to the stuff we actually care about validating much more easily. Something like the below example would feel pretty nice to me.
This has a few benefits, two big ones being
Some of the immediate cons I can think of though.