Selenium Java - Page Object Model Query - java

Imagine there is a page say http://google.com/AddUser and here you enter details for a record and click save. Once you do this the page redirects to
http://google.com/userList
where you can see list of users including the new record you just entered.
If we are going by page object model, the method to enter details and save record should exist on AddUser.java and the method to validate if the record was actually saved and displayed should be on UserList.java
If we consider addUser and userList are the corresponding objects for both classes it will be something like below :
addUser.enterDetailsSaveRecord();
userList.validateSavedRecord();
So in my Test case i would need to call 2 separate methods, one for the action and other to validate.
Both AddUser.java and UserList.java have BasePage.java as the superclass.
Is there a way to club them both into a single method or is there something I'm going about in a wrong way and is there a better approach?
Thank you

Using PageFactory you are having 2 PageObjects as AddUser.java and UserList.java. So assuming you are passing the appropriate arguments while invoking the methods, the following works for you:
addUser.enterDetailsSaveRecord();
userList.validateSavedRecord();
But a word from Best Practices, Assertions should be done in a seperate utility/package/class which is in similar line with #JeffC comment:
Best practice is to keep the validation code out of the page objects
Hence, you should be creating a seperate common utility/package/class which will handle all the Assertions. You can call the class containing the Assertions from your PageObject class as well.
So your entire Test Environment will contain 3 Packages. One package containing the main()/#Test class, one package containing the PageObjects e.g. AddUser.java and one Utility package with the class for containing the Assertions e.g validateSavedRecord().

I don't see anything wrong with your approach either, although, my approach is usually to logically separate functional interaction with the application from testing functions. So, I would still have
addUser.enterDetailsSaveRecord();
but for userList I would use
UserItem foundUser = userList.findUser(targetUser);
where UserItem is a row in the table of users. My test would then verify that foundUser was correct.
Although this ends up with a few more lines of code, it results in the object model cleanly and simply modeling the object under test, and the testing code being found in the test itself.

Your approach is correct. These methods should belong to different pages.
Please update method as:
public UserList enterDetailsSaveRecord() {
// your code to save the details
return new UserList();
}
thus you can use it as:
addUser.enterDetailsSaveRecord().validateSavedRecord()

Related

Test for checking object values inside class

I have a javafx application which has a few fields, like an anchorPane. In its .fxml file, that anchorPane has a few fields like these
How can I test these values? I'm sure that JUnit can test object values, so I was wondering if I can make something like
Assertions.assertThat(mainAnchorPane.getId()).isEqualTo("mainAnchorPane");
Not sure but that might be as simple as instantiating an entity class (lets name it Person) and do something like
Person person = new Person("Maria");
Assertions.assertThat(person.getName()).isEqualTo("Maria");
The point here is that I'm not sure how can I inject the object values from my class into the tests, assuring that Person (or AnchorPane) from my class has the same values in my test.
Any thoughts?
Thanks in advance!
I don't know if you already thought about this, but there is a test library called TestFX. It is made to test JavaFX applications easily. Maybe it can help you:
https://github.com/TestFX/TestFX/
For example you can proof the input of textfields or simulate mouse clicks. You can find more information on the given url.

Java - Creating a class to dynamically determine if user has access to the calling method

I have tried doing a search for this but I fear I may not be wording what I want to do very well.
Currently, we have about a hundred action classes in our application with each determining if a user has access to it. I would like to make a class that can figure out the calling method, what permissions are required for it, and if the user has those permissions. Unfortunately, I don't really know how to even get started with this as each class may have slightly different requirements.
I'm happy to add more explanation if needed but as I said, I'm not sure I'm wording what I'm trying to do very well so if anyone has a better way of putting it that gets me some google results or a link to a related question here that's already been answered, I know I'd appreciate it.
current permissions checks look like below. This is a simple implementation, there are usually multiple profile checks in one if block.
If (scc.getUser().getCurrentProfile().getSystemAdmin() != 1) {
logIllegalAccess(log);
break;
}
IMHO the most elegant solution would make use of annotation processing. The idea is that you would annotate action classes with a custom annotation, something like:
#RequiredPermission(Permissions.SYSADM)
class ActionA {
public ActionA newInstance() {
return new ActionA_Gen(new ActionA());
}
private ActionA() {...}
...
}
Action classes would have to have a newInstance() method to be used to create instances instead of calling new. The method would create an instance of a class by the same name with _Gen extension. This class would have one method for each method in the original action class, which would perform a permission check and call the corresponding method in the original class instance that was passed to its constructor.
The _Gen class would be generated by an annotation processor.
Note that by using reflection it might be possible to move the newInstance() method in a common superclass.

Selenium test organisation of classes

Ok selenium gurus a bit of an open question here. I am looking for some guidance on the best way to organize my tests that use object oriented principles.
At the moment I am creating a testrunner main class from which I create an object of a general test class. I am then extending this class for more granular tests.
An example.
I need to open the browser, enter the url, log in as a user.
From there you can access perhaps 40 different links each containing their own pieces of functionality. E.g. A profile link which leads to a profiule screen where you can enter introduction text, upload a picture, change a picture etc...
Another example would be a notification screen where you can navigate to view and mark as read etc...notifications you have received.
I can write the code to test this by for example by creating a ton of methods in that 1 class and then calling these from the main testrunner class. There has to be a better organized way where I can have a separate class for functionality but wont I then have to create a new object for each test?
Sorry about the confused post I'm trying to learn Java thoroughly and selenium also.
EDITED
I have copied the process of creating a page object hybrid model that is documented in the YouTube video:
https://www.youtube.com/watch?v=gxwh8D_tx-0
I created a Pages package which contains all of the Page specific class such such ProfilePage, NotificationPage etc...
I have a second package which contains the tests and a testbase class which generates the driver object, opens the browser.
I want to get to the stage where in my tests class I can have a specific class for a test for example:
class test_that_user_can_upload_profile_picture
When I create such a class I have methods inside the class such as: test_that_navigation_to _profile_page_successful()
test_to_upload_valid_picture()
Should such navigation methods be inside this class?
Also I find that in order to access my methods from a package I need to mark my methods as static. Is this ok? I noticed on the youtube video the instructors methods were not static. Looking at the setup I dont quite understand why I cant access the methods unless I mark them as static. The error i get is
"Cannot make a static reference to a non-static method"
Here is my setup:
Also Im finding that in my ProfilePageNavigation class I have a bunch of methods that run in a specific order based alphabetical order.
Is it simply the case I should just have 1 method in each test class and just call the page classes methods(or any other pertinent class) to execute this test? If it is just 1 method inside each test class then wouldnt I have too many test classes each with a name like (for example) upload_valid_profile_picture with a method using the same name? and then another class with upload_invalid_profile_picture with it's method. I dont want to go down that path - how do I resolve that?
Also all my Pages class methods have to take WebDriver driver as a parameter is there any way around this - it is a lot of duplication.
If you could point me on the right track and let me know in it is ok to have the pages class methods as static it would be appreciated.
I guess I just want to know whether I am on the right track or going down the wrong route at this early stage.
#tarquin - you can find many articles on that #web, There are multiple ways to handle your code and work with it, my way is :
Create a objects repository in notepad or excel, from where you can pick/change/manage all your objects.
Create a class with all re-usable methods.
Create a class of your tests.
Thanks
Keshav

When to Stop Defining FindBy's in the Object and Move Them to the Test

So I have an interesting conundrum I was curious to get some feedback from other Webdriver framework architects. Currently I follow a pretty standard execution model:
baseobject
pageobject (extends baseobject)
Junit testobject (references one or multiple pageobjects)
Within my pageobjects I chose to define my findBy UI mappings as variables, and in-turn reference them within the various methods I write for that pageobject. I find this works very well. However, one item I am waffling on is how to handle method design for pages (and their respective pageobject) when there exist potentially 50 separate hyperlinks.
My inclination and design thus far has been to create methods (I think of them as services really) for each link on most pageobjects I've created so that #Test I can simply call the method I want and be done with it. This eliminates the potential for test maintenance...standard practice I know. But I am now trying to decide...does it make sense to create 50 methods, one for each link for a page object, or do I go against my wishes and pass in linktext from the test itself, feeding into a single method that builds the findBy using that passed in parameter.
On one hand there is way less code within the pageobject, but on the other, tests become more brittle. There is potential for these links to be references in hundreds of tests.
Here is a brief example of my model:
classname extends baseobject{
By someLocator = By.linkText("some text");
By someOtherLocator = By.linkText("some other text");
By andAnotherLocator = By.id("someid");
public void someLinkMethod(){
driver.findElement(someLocator).click();
}
public void someOtherLinkMethod(){
driver.findElement(someOtherLocator).click();
}
public void someidMethod(){
driver.findElement(andAnotherLocator).click();
}
}
Thus we come to the end of the question. This model works great for test design. My services (methods) are insulated and easily maintainable. But what would I do if there were 50 UI mappings for links instead of 2 as I have shown above? I toyed with the following design, but really dislike it #Test:
public void selectFromLeftBar(String barItem){
driver.findElement(by.linkText(barItem)).click();
}
Any thoughts would be greatly appreciated!
Do it in your page object class. Here are the reasons:
What does your code do if your page changes the link text? You have to go into each test and change that text, even if the link does the same thing.
What happens if your page removes that link? You are stuck with the same problem, namely, having to find each time you call that link. If its a method...then you delete the method, and your IDE notifies you of each instance that you used it.
Finally, you are providing a standard interface for the test. If you make an exception here, what would stop you from passing other things into your page?
As a side note, I would recommend only mapping elements that you are going to use. I've found that if I map out every element I could possibly ever need then I end up with a massive class filled with fluff and less time on my hands.

Provide data to a method using aspect oriented programming

I'm learning AOP and am comfortable with Pointcuts, Advices etc.
What am going to ask, am pretty sure is not possible, but want to ask anyways.
I have a method which takes a userId, fetches the user's record from a database and then does something to the record. I have like twenty different methods that do different things, but all of them take the userId as input and fetch the record from database. This to me looks like a cross cutting concern that can be pulled into an aspect.
But how? I know I can access the arguments (userId in this case), access the return value of the method and catch the methods exception. But how do I give the method something to work with (record in the database in this case?)
public String printUserDetails(String userId)
{
Record record = Database.fetchRecord(userId);
System.out.println(record.getDetails());
return record.getTitle();
}
So, is there a way to pull that database accessing code into an aspect?
One way I can think of is declare something like the following for input
class RequestObject
{
String userId;
Record record;
}
and inject the record in the Aspect and then call proceed(). But this somehow feels wrong.
IMO, resolving a user, using the userid, is not a cross-cutting concern and hence aspect is not the right way. The first landing page that receives a userId should actually resolve it to UserRecord and from then on, the userRecord should be the one moving around in the application.
A simple analogy I can draw to your scenario from one of my applications is, all authenticated servlets expect the servletRequest.getRemoteUser() to return the valid user login corresponding to the user sending the request. We decorated the HttpServletRequest to resolve this to a User object in our application and all the authenticated servlets downcast the HttpServletRequest to AuthenticatedServletRequest and extract this object. No one else within the application tries to resolve a user login anymore.
You cannot access a method's local variables from AspectJ if this is what you wanted to know.
The rest of the question is rather about design and the answer dependent on what you want to achieve. You can avoid code duplication in multiple methods using a template method design pattern. You can inject real or mock objects into classes if you refactor them to have a member instead of local variables. It is another question if you create the member by directly refactoring your classes or via AspectJ's (ITD)[http://www.eclipse.org/aspectj/doc/next/progguide/starting-aspectj.html#inter-type-declarations] mechanism. A third question would be if you possibly want to use an aspect for caching in order to avoid fetching the same object from the database multiple times.
I am not sure what exactly you want to achieve, so I cannot answer more specifically.

Categories

Resources