Using different sets of page objects with the same selenium tests - selenium

[This is cross-posted with SQA - https://sqa.stackexchange.com/questions/35081/using-different-sets-of-page-objects-with-the-same-selenium-tests]
I'm working on a selenium test suite for a set of similar websites. The test suite would be execute separately for each site and the tests in the suite are applicable to all websites.
These websites are built on the same underlying platform, however have different theme/scheme and therefore page objects for these sites need to be different. This is not a case of one or two selectors being different, but majority of selectors different - yet the rest of the structure is the same.
I can easily create two (or three, or whatever) sets of page objects, however I can't figure out how to tell the test executor (Cucumber cli in my case) which page objects to use.
The closest I can come up with is use different package names with common base classes and then individual pages extending from the common base classes. Another possibility is to extract all the selectors into property files and load one or another based on an input parameter, however this would preclude me from using PageFactory. I can also, probably, create separate sets of page objects in different source sets and then compile one or the other based on my need - but, again, I can think of the theory, yet not the execution.
So, what's the right approach and how to achieve this? If it matters, the project is built using gradle.

Since the tests are suitable for all the sites I will assume the only difference between the pages is the selectors behind the objects.
cssSelector and xpath provides or. Assuming text field has ID id1, id2 or id3 depends on the page you can use
#FindBy(how = How.CSS, using = "#id1, #id2, #id3")
private WebElement textField;
This will return the WebElement matching one of the ids.

The solution turned out to be a custom ElementLocator and ElementLocatorFactory with a corresponding custom annotation. It's a bit more work, but it's a very clear solution. I published it on github. In short, the implementation allows to do this:
public class MyPage {
#SearchWith(page="MyPage", name="myElement", locatorsFile="{locators}")
WebElement someElement
...
}
Then run the whole test with -Dlocators=site1.json or -Dlocators=site2.json - and corresponding locators will be loaded from one or the other. It even allows to specify -Dlocators=[site3.json] and load locators from site3.json resource (as obtained using this.getClass().getResourceAsStream(locatorsFile))

Related

Access closure property names in the content block at runtime

I want to evaluate my content blocks before running my test suite but the closures' property names is in bytecode already. I'm ooking for the cleanest solution (compared with parsing source manually).
Already tried solution outlined in this post (and I'd still wind up doing some RegEx/parsing) but could only get it to work via script execution engine. It failed in IDE and GroovyConsole. Rather than embedding a Groovy script in project's code, I thought I'd try using Geb's native classes.
Is building on the suggestion about extending Geb Navigators here viable for Geb's PageContentSupport class whose contentTemplates contain a LinkedHashMap of exactly what I need? If yes, would someone provide guidance? If no, any suggestions?
It is currently not possible to get hold of all content elements for a given page/module. Feel free to create an issue for this in Geb's bug tracker, but remember that all that Geb can provide is either a list of content element names or a map from these names to closures that create these elements.
Having that information isn't a generic solution to your problem because it's possible for content elements to take parameters and there are situations where your content elements will be available on the page only after some other actions are performed (for example you have to click on button to reveal a section of a page that uses ajax to retrieve it's content). So I'm afraid that simply going over all elements and checking if they don't throw any errors will not cut it.
I'm still struggling to see what would "evaluating" all content elements prior to running the suite buy you. Are you after verifying that your content elements still work to get a faster feedback than running the whole suite? I'm pretty sure that you won't be able to fully automate detection of content definitions that don't work anymore. In my view it will be more effort than it's worth.

webdriver :How to automate a page that appears sometimes in workflow?

I'm automating a workflow (survey) . This has few questions on each page.
Each page has few questions and a continue button .Depending on your answers next pages load. .How can I automate this scenario.
TL;DR: Selenium should only form a part of your automated testing strategy & it should be the smallest piece. Test variations at a lower level instead.
If you want to ensure full coverage of all possibilities, you've two main options:
Test all variants through browser-based journey testing
Test variations outside of the browser & just use Selenium to check the higher-level wiring.
Option two is the way to go here — you want to ensure as much as possible is tested before the browser level.
This is often called the testing pyramid, as ideally you'll only have a small number of browser-based tests, with the majority of your testing done as unit or integration tests.
This will give you:
much better speed, as you don't have the overhead of browser load to run each possible variant of your test pages.
better consistency, i.e. with unit tests you know that they hold true for the code itself, whereas browser-based tests are dependent on a specific instance of the site being deployed (and so bring with it the other variations external to your code, e.g. environment configuration)
Create minimal tests in Selenium to check the 'wiring'.
i.e. that submitting any valid values on page 1 gives some version of page 2 (but not testing what fields in particular are displayed).
Test other elements independently at a lower level.
E.g. if you're following an MVC pattern:
Test your controller class on it's own to see that with a given
input, you get are sent to the expected destination & certain fields populated in the model.
Test the view on it's own that given a certain model, it can display all the variations of the HTML, etc.
It will be better to give if else statements and automate the same. Again it depends on how much scenarios u need to automate.

Can HTMLUnit package be used with PhantomJsDriver.java

I am using "org.openqa.selenium.phantomjs.PhantomJsDriver" Java class.
At times, I need to identify whether a given WebElement is a particular type of web element; eg: Is this webelement a input type element or not.
This does not seem to come with PhantomJsDriver package.
"com.gargoylesoftware.htmlunit." package seems to have useful wrappers on top of web elements. I can write code like "element instanceof HtmlInput".
Question here is
- Can I really HTMLunit package with phantomjsdriver ? Am I using two libraries which are not supposed to be used with one-another ?
No. Unfortunately, you can't do this the way you're doing it. PhantomJsDriver is backed by WebKit, while HtmlUnitDriver is backed by HtmlUnit which has its own browser core. Selenium is able to wrap both these (and some more) under one hood, but we can't use them interchangeably.
There are, however, different ways of doing what you're trying to do, the best probably being using Selenium's own methods getTagName() and getAttribute() if needed.
If you ran getTagName() on your input element, it would gladly return "input".

Fitnesse Slim + Selenium: Parameterized Suite Hierarchy for Several Browsers?

I'm starting with Selenium and FitNesse. My goal is to create an acceptance tests suite which can be run easily in different browsers.
At first I wrote a very short wrapper around Seleniums WebDriver. The wrapper functions are used in Scenario Tables, Script Tables and Query Tables. So far, everything is fine.
My idea was to create a wiki page hierarchy called ParameterizedSuites, which has sub-suites and tests in any possible depth. Now I wanted to create one suite called FirefoxSuite defining an variable ${BROWSER} with value "firefox" and include the ParameterizedSuites only. In ParameterizedSuites.SuiteSetUp a WebDriver instance will be instantiated using ${BROWSER}.
But my idea does not work. It seems that I must include every SetUp, TearDown, Suite and Test page seperately? Is my idea completely wrong or am I missing something?
Does anybody something similar?
Hope my description is clear enough to understand the scenario.
Kind regards,
Andi
I think what you want is SymbolicLinks. You can use Symbolic Links to include a subtree of the wiki into a different place in the wiki.
For more information on SymbolicLinks, check your local users guide or the copy online: http://www.fitnesse.org/FitNesse.UserGuide.FitNesseWiki.SymbolicLinks
A common way to do this is to actually create your ParameterizedSuite and then symbolically link it into the Pages that define the configuration and supply specialized SetUp and TearDown pages. This is sort of the oposite of what you are describing, but I think what you are doing could work as well, provided you use SymbolicLinks to make the pages part of the wiki structure of your parameterized tests.
FrontPage
SuiteOne
TestOne
ConfigurationOne
SetUp
TearDown
SuiteOneSymolicLink
ConfigurationTwo
SetUp
TearDown
SuiteOneSymolicLink
In the structure above, SuiteOne can be run via the symbolic link in ConfigurationOne or ConfigurationTwo. Variables defined in the ConfigurationOne or ConfigurationTwo pages will inherit to SuiteOne when is is run via the SuiteOneSymbolicLink in each configuration hierarchy. Additionally, the SetUp and TearDown from the Confiugration Pages will be inherited as well.

TestNG & Selenium: Separate tests into "groups", run ordered inside each group

We use TestNG and Selenium WebDriver to test our web application.
Now our problem is that we often have several tests that need to run in a certain order, e.g.:
login to application
enter some data
edit the data
check that it's displayed correctly
Now obviously these tests need to run in that precise order.
At the same time, we have many other tests which are totally independent from the list of tests above.
So we'd like to be able to somehow put tests into "groups" (not necessarily groups in the TestNG sense), and then run them such that:
tests inside one "group" always run together and in the same order
but different test "groups" as a whole can run in any order
The second point is important, because we want to avoid dependencies between tests in different groups (so different test "groups" can be used and developed independently).
Is there a way to achieve this using TestNG?
Solutions we tried
At first we just put tests that belong together into one class, and used dependsOnMethods to make them run in the right order. This used to work in TestNG V5, but in V6 TestNG will sometimes interleave tests from different classes (while respecting the ordering imposed by dependsOnMethods). There does not seem to be a way to tell TestNG "Always run tests from one class together".
We considered writing a method interceptor. However, this has the disadvantage that running tests from inside an IDE becomes more difficult (because directly invoking a test on a class would not use the interceptor). Also, tests using dependsOnMethods cannot be ordered by the interceptor, so we'd have to stop using that. We'd probably have to create our own annotation to specify ordering, and we'd like to use standard TestNG features as far as possible.
The TestNG docs propose using preserve-order to order tests. That looks promising, but only works if you list every test method separately, which seems redundant and hard to maintain.
Is there a better way to achieve this?
I am also open for any other suggestions on how to handle tests that build on each other, without having to impose a total order on all tests.
PS
alanning's answer points out that we could simply keep all tests independent by doing the necessary setup inside each test. That is in principle a good idea (and some tests do this), however sometimes we need to test a complete workflow, with each step depending on all previous steps (as in my example). To do that with "independent" tests would mean running the same multi-step setup over and over, and that would make our already slow tests even slower. Instead of three tests doing:
Test 1: login to application
Test 2: enter some data
Test 3: edit the data
we would get
Test 1: login to application
Test 2: login to application, enter some data
Test 3: login to application, enter some data, edit the data
etc.
In addition to needlessly increasing testing time, this also feels unnatural - it should be possible to model a workflow as a series of tests.
If there's no other way, this is probably how we'll do it, but we are looking for a better solution, without repeating the same setup calls.
You are mixing "functionality" and "test". Separating them will solve your problem.
For example, create a helper class/method that executes the steps to log in, then call that class/method in your Login test and all other tests that require the user to be logged in.
Your other tests do not actually need to rely on your Login "Test", just the login class/method.
If later back-end modifications introduce a bug in the login process, all of the tests which rely on the Login helper class/method will still fail as expected.
Update:
Turns out this already has a name, the Page Object pattern. Here is a page with Java examples of using this pattern:
http://code.google.com/p/selenium/wiki/PageObjects
Try with depends on group along with depends on method. Add all methods in same class in one group.
For example
#Test(groups={"cls1","other"})
public void cls1test1(){
}
#Test(groups={"cls1","other"}, dependsOnMethods="cls1test1", alwaysrun=true)
public void cls1test2(){
}
In class 2
#Test(groups={"cls2","other"}, dependsOnGroups="cls1", alwaysrun=true)
public void cls2test1(){
}
#Test(groups={"cls2","other"}, dependsOnMethods="cls2test1", dependsOnGroups="cls1", alwaysrun=true)
public void cls2test2(){
}
There is an easy (whilst hacky) workaround for this if you are comfortable with your first approach:
At first we just put tests that belong together into one class, and used dependsOnMethods to make them run in the right order. This used to work in TestNG V5, but in V6 TestNG will sometimes interleave tests from different classes (while respecting the ordering imposed by dependsOnMethods). There does not seem to be a way to tell TestNG "Always run tests from one class together".
We had a similar problem: we need our tests to be run class-wise because we couldn't guarantee the test classes not interfering with each other.
This is what we did:
Put a
#Test( dependsOnGroups= { "dummyGroupToMakeTestNGTreatThisAsDependentClass" } )
Annotation on an Abstract Test Class or Interface that all your Tests inherit from.
This will put all your methods in the "first group" (group as described in this paragraph, not TestNG-groups). Inside the groups the ordering is class-wise.
Thanks to Cedric Beust, he provided a very quick answer for this.
Edit:
The group dummyGroupToMakeTestNGTreatThisAsDependentClass actually has to exist, but you can just add a dummy test case for that purpose..