Best Design Pattern for Selenium Automation for Large Scale Application - selenium

I would like to know the best design pattern for Selenium for automating large scale SaaS Product.
Looking for all your comments on this.
and for large scale application i preferred keeping my xpath's for web elements in page object file. but my lead wants me to keep xpath's in Properties file and we should access Properties file for every xpath's. Is this a good approach of keeping xpath's in properties file for Large Scale SaaS application?

Your leed wants you to implement Object Repository Pattern.
I think this idea is as old as HP QTP (QuickTest Professional) where it is extensively used - but I may be wrong, it's only my opinion.
In short (a quote from the above link):
Object Repository is a centralized location where we can store objects
information, it acts as interface between Test script and application
in order to identify the objects during the execution.
We always recommend using external file for object repository rather than hard coding the objects and its properties
directly into our code. If you are asking me why this is? Reason is as
it reduces the maintenance effort and provides positive ROI, for
example say any of the object properties change within our application
under test, we can easily change it in external object repository
file, rather than searching and doing updates for that object
individually in the code
Think of a scenario where you have a Webpage and it has multiple
sections, multiple frames and hundreds of WebElements. Obviously you
do not want that once you type the page name and it will give you all
the elements available on the webpage. If there are few elements, it
is fine to have the same structure but if there are many then it is
advisable to divide your page in to different sections for e.g.
header, footer, left navigation, center content and right navigation.
Then categories each WebElement under their parent element.
I think this pattern does not stand in contradiction to the Page Object Pattern, they can both work very well together. It brings greater transparency to the project and forces developers/testers to maintain better readability of the project, which helps in maintaining it in the future.
But the above is only a bit of theory, one may ask how this pattern can help in real life?
Consider a simple example. Let say that there is a piece of code:
public class SomePageObject{
.....
.....
public void doSomething(String value){
findElement( By.xpath("//*[ #class='left-content']//button[ contains( ., 'list-selector' )]") ).click();
wait.until( ExpectedConditions.visibilityOfElementLocated( By.xpath( String.format( "//li[ *[ text() = '%s' ]]", value ))).click();
}
I have seen code like this hundred of times. What do you think about this code ? Yes, it follows the well known Page Object Pattern. But it is horrible.
Looking at this code, can you guess what is it doing? Definitelly No.
What error message will you get in the log when this code will break due to change in UI of second element ? Most likely something like this:
org.openqa.selenium.TimeoutException: Timed out after 30 seconds
waiting for visibility of element located by By.selector: //li[ *[ text() = 'New York' ]]
Can you guess, looking only at this error message, which part of the application it concerns and where it can be found in the code ? No.
An automation engineer can find it in code looking at stack trace but a junior tester who doesn't know java, selenium etc. cannot fix it looking only on the error and a printscreen (if available).
In many cases in order to fix the error, the automation engineer needs to run this test case on a local machine to replicate the issue.
How can it look like using Object Repository Pattern ?
There can be a property file which may look like this:
....
orderPage.citySelectButton=//*[ #class='left-content']//button[ contains( ., 'list-selector' )]
orderPage.citySelectListElement=//li[ *[ text() = '%s' ]]
...
...
and a code which may look like this:
public class SomePageObject{
.....
.....
public void doSomething(String value){
objRepoFacade( "orderPage.citySelectButton" ).click();
objRepoFacade( "orderPage.citySelectListElement", value ).wait().click();
...
)
}
The error message in the log may look like this:
RuntimeException: time out waiting for element: orderPage.citySelectListElement
located by By.selector: //li[ *[ text() = 'New York' ]]
And now even the junior tester, looking only on this error message, is able to easily guess in which part of the application the error occurred, and which exactly element is broken. The tester may be trained how to inspect an element on the page using the developer console (F12), correct the selector in the procerties file, and fix the issue on his own without the help of automation engineer and without touching the code at all.
Preasumbly from your leed's point of view the latter (Object repository) is a better solution because it can employ more junior testers and fewer automation engineers and reduce costs.

Related

Cro Template as Object

The Scenario
I've been using templates in Cro (documented at https://cro.services/docs/reference/cro-webapp-template), and have enjoyed that there are subs in them.
I currently have a 'main' template, and some reports, let's say report1, report2, and report3.
Let's say that, from report3, I want to include an array of report1.
Now, let's say that the reports each have the following subs:
init: Some Javascript initialisation code (that should only be included once, no matter how many instances of the report are used)
HTML: Some HTML code that should be included for each instance of the report (with a few parameters to differentiate it, but that, due to the restriction of the Javascript framework, may not contain any <script> or <style> tags
data: A snippet of Javascript that again has to be repeated for each time the report is included
Currently I have each of the above in a separate sub in the template.
The Problem
Redeclaration of symbol '&__TEMPLATE_SUB__report-initial'.
The Question
While I can pass a report name (eg. "report1") to the main template, what I'm lacking is a way to have the main template call the subs on the report name that has been passed in, since there may be multiple reports involved.
Ideas I've tried
What would be ideal is if I could somehow create a "report" class that inherits from the template, and pass instances of the template class into the main report, and then call the subs as methods on the report class. However, I've been unable to figure out a way to do this.
I can see three likely options here:
My difficulty may be that I'm not thinking "The Cro Way". If there's a better way to achieve what I'm trying to do, please let me know
There may be a way to achieve what I want, and I've just been unable to understand the documentation (or it may be missing)
While unlikely, it's possible that Cro hasn't been designed with this kind of possibility in mind.
Any help anyone can provide would be appreciated.
Thanks!
Edit: I think a macro that can have multiple (named) "bodies" would solve the problem.
It looks like &__TEMPLATE_SUB__report1-initial is a global that is redeclared when you import report1 into report3. May I suggest to try and use template fragments instead of the whole template?
my initial response to your question is "please can you provide a minimal reproducible example of your code so that we can get a deeper view of the context and have something that we can experiment with"
my current understanding of what you need is "to use raku style classes & objects (with callbacks) in a Cro template setting" - and that the standard ways of doing this such as associative access to a nested topic variable are too limited
in itself, this is not necessarily a weakness of raku / Cro in that the power of a template slang needs to be limited to avoid potential security issues and, as with most template systems, is a bit more prosaic than a full blown coding language
my guess is that Cro template-parts which can chunk up web parts and steps in and out of the (real raku) root block can, depending on how you chunk things up, handle the report data structure that you describe - have you tried this?
if this is still not tenable, there are a couple of ways to expand the options such as dependency injection and route handlers

Is Cmd.map the right way to split an Elm SPA into modules?

I'm building a single page application in Elm and was having difficulty deciding how to split my code in files.
I ended up splitting it using 1 module per page and have Main.elm convert the Html and Cmd emitted by each page using Cmd.map and Html.map.
My issue is that the documentation for both Cmd.map and Html.map says that :
This is very rarely useful in well-structured Elm code, so definitely read the section on structure in the guide before reaching for this!
I checked the only 2 large apps I'm aware of :
elm-spa-example uses Cmd.map (https://github.com/rtfeldman/elm-spa-example/blob/cb32acd73c3d346d0064e7923049867d8ce67193/src/Main.elm#L279)
I was not able to figure out how https://github.com/elm/elm-lang.org
deals with the issue.
Also, both answers to this stackoverflow question suggest using Cmd.map without second thoughts.
Is Cmd.map the "right" way to split a single page application in modules ?
I think sometimes you just have to do what's right for you. I used the Cmd.map/Sub.map/Html.map approach for an application I wrote that had 3 "pages" - Initializing, Editing and Reporting.
I wanted to make each of these pages its own module as they were relatively complicated, each had a fair number of messages that are only relevant to each page, and it's easier to reason about each page independently in its own context.
The downside is that the compiler won't prevent you from receiving the wrong message for a given page, leading to a runtime error (e.g., if the application receives an Editing.Save when it is in the Reporting page, what is the correct behavior? For my specific implementation, I just log it to the console and move on - this was good enough for me (and it never happened anyway); Other options I've considered include displaying a nasty error page to indicate that something horrible has happened - a BSOD if you will; Or to simply reset/reinitialize the entire application).
An alternative is to use the effect pattern as described extensively in this discourse post.
The core of this approach is that :
The extended Effect pattern used in this application consists in definining an Effect custom type that can represent all the effects that init and update functions want to produce.
And the main benefits :
All the effects are defined in a single Effect module, which acts as an internal API for the whole application that is guaranteed to list every possible effect.
Effects can be inspected and tested, not like Cmd values. This allows to test all the application effects, including simulated HTTP requests.
Effects can represent a modification of top level model data, like the Session 3 when logging in 3, or the current page when an URL change is wanted by a subpage update function.
All the update functions keep a clean and concise Msg -> Model -> ( Model, Effect Msg ) 2 signature.
Because Effect values carry the minimum information required, some parameters like the Browser.Navigation.key are needed only in the effects perform 3 function, which frees the developer from passing them to functions all over the application.
A single NoOp or Ignored String 25 can be used for the whole application.

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.

how to get knowing more about a class behaviour without looking at its manual?(a fundamental question about how to dive more into OOP)

I'm practicing OOP for 2 years (for real) and I know how to consume objects and packages and I'm developing stuffs mostly using C# .
but I have a problem with consuming unknown objects and packages as an instance :
for now I am working on an enterprise like website and for part of our job we need to consume RSS. I decided to use "System.Xml.Xpath"
and my real problem is:
for using system.xml.xpath I should look at manual and read it carefully and I don't want to do that every time.A plain example of that is like following code :
XPathDocument xp = new XPathDocument(sites[2]);
XPathNavigator nav = xp.CreateNavigator();
XPathNodeIterator it = nav.Select(xpath3);
foreach (XPathNavigator n in it)
{
//get elements here
}
//another way of iterating elements is
while(it.movenext())
{
//it.current.Value;
}
for the "foreeach" part I got it from MSDN manual and I guess I could get this simple fact by looking at class structure.
but I don't know which structure I should look.
I know how to read tooltips and I'm familiar with things like : [] / collection / enum /generic / Ienumerable / Idisposable etc...
but I think there is something about reading class behaviors and I'm missing that part.
for make it more lucid :
I know whenever we have a class that inherited from IEnumerable so we can use foreach statement against that class to iterate it through
my real problem is I think classes are self described enough to not to look at manuals all the time but I don't know how/where to read those descriptions of classes so I need your advice to get more familiar with how to reading classes without looking at manuals.
best regards.
Classes can (and should) be documented with source code comments, and in many languages you can generate API documentation from these comments (in HTML, XML or other format). In Java it is called Javadoc; I don't know the C# term. If this is what you call "manual", then this is your primary source of information. Other than reading the source code comments and the code itself (which you often don't have access to, especially in the MS universe). If you don't find enough information in the API documentation, you can always try googling for more explanation, tutorials or usage examples.
Hope this helps; I am not entirely sure I understood your question though. If this is not the answer you are looking for, please clarify.

GWT testing without GWTTestCase and the DOM

Can I test my client side GWT code without GWTTestCase? I've heard somewhere (I think it was one of the Google IO 2009 conferences) that they were successfully testing their code with a fake DOM, in the JVM and not in Javascript with the DOM. That would be brilliant. The point of this would be to gain speed (order of magnitude). Does anybody have any idea about how to do this? My first question on stack overflow, hope I'm doing this right.
Thanks.
Eugen.
You should check out the Google I/O session by Ray Ryan.
Basically, you can use the Model/View/Presenter pattern and abstract away all the DOM-accessing code to the 'View' portion. By doing this, you can create a mock view and test the model/presenter using standard junit tests, running via the jvm, without the need for a browser or a DOM
Not quite what you're looking for, but you should use the Model-View-Presenter pattern. Any code that requires the DOM should go in your View classes, and should be as dumb as possible. Complex logic goes in your Presenter classes. You can then test your presenter classes without needing a GWTTestCase.
E.g, a view might have a method like:
void setResponseText(String text);
Your presenter test case can then look something like:
void testSayHi() {
expect(mockView.setResponseText("hi there"));
replayMocks();
presenter.sayHi();
verifyMocks();
}