How to parameterize the locators in selenium page object model with TestNg or any other framework? - selenium

I need to automate two applications in which the navigation almost looks similar but the locators (xpath,id etc.,) are difderent.So,I have created a project with TestNg in eclipse and able to run one testcase for one application.But to maintain code reusability, I wanted to parameterize the locators( eg: in one application it is "//div[contains(text(),'abc')]" whereas in the other application it is "//div[contains(text(),'def')].Searched in google but nothing is helpful.
Please let me know your comments. Am okay to start a new framework where the locators can be parameterised.

Define all your locators in application like Excel,
The structure of Excel should be in a way that, the first row refers to key, the Second row refers to the locators for "application A", the third row refers to the locators for application B corresponding to the key. The structure of excel should be as below
Excel reader class should be row iterator, the first row serves as Key and corresponding row serves as values. first iteration row 1 and row 2 values are placed in key and value mapping in a hashmap and the execution will be on Application A.

I would suggest you to keep different packages for test and page(locators).
In the locator you can create java classes for different kind of pages that you have in your application, where you can keep our locators as per the pages(java class) and can create methods where you can parameterize them for reusability.
In the test class you'll have to just create objects of the pages(java class) so that you can use the methods
Hope this helps!

In your specific case you can try to write a utility function like this:
public static String setlocator(String param){
String test = "//div[contains(text(),'" +param+"')]";
return test;
}
and call that function in your any application to get the locator.

Related

Selenium Apache POI - What is the best way to Read Data from Excel and use that data in Test scripts

I have a Page Object Model project structure. The project structure is as follows:
src
->com.actions
->com.config
->com.pageObjects
->com.testSuite
->com.utils
In utils package have excel class from where I read test data from excel by calling getCellData method which I have defined in excel class.
In pageObjects package, I have all the locators of the page using Page factory.
In actions package, I have the actions which needs to be done on particular page. So, here is my query - As of now, I'm getting data from excel sheet by passing row and column numbers. here is my code:
ExcelUtils.setExcelFile(Constant.TestData_Path + Constant.TestData_FileName,"User Info");
AdminLoginPage.username.sendKeys(ExcelUtils.getCellData(1, 0));
Like this I was getting data from excel till now, this will be not be feasible in long run it seems. Can someone help or suggest a best way to do the same. Thanks in advance!

calling RankToPosition() and _onMoveToPositionClicked

I have a situation where i'd like to enter a "3" into a textbox on a user story grid, call something like RankToPosition(3) to move that user story row to position 3 in the current rank. Within the same grid, the idea is to have a textbox on each row, so the row beneath may have a 4 in there, and when i click SUBMIT, the entire table would be processed by using the numbers in the row textbox and calling RankToPosition(#). This is like the Netflix queue. There have been similar questions on here, but my thought is to just call the underlying method alluded to here as "_onMoveToPositionClicked":
https://help.rallydev.com/apps/2.0rc3/doc/source/MoveToPositionMenuItem.html#Rally-ui-menu-item-MoveToPositionMenuItem-cfg-rankRecordHelper
If i could iterate through the table grid, store initial rank values (i realize they're not just integers), and pick the new text values up, run code to call the _onMoveToPositionClicked beneath the scenes, it may accomplish a bulk rank grid for when users have 200+ items to manage, for instance.
Any insight you have for just calling this in custom code would be helpful. Any solution for representing this functionality would be appreciated. I am currently using Rally 2.0rc3.
Thank you for your time
Is it possible to upgrade to a newer version of the App SDK? 2.0rc3 is a very old pre-release. The latest is 2.1: https://help.rallydev.com/apps/2.1/doc/
In any case, the way ranking is performed is relative to another object via the rankAbove or rankBelow parameters. So given the record you want to rerank:
record.save({
params: {
rankAbove: '/hierarchicalrequirement/12345'
}
});

How to customize Selenium TestNG default report or create new HTML report?

I tried ReportNG, but it is not updating the report now & I found that ReportNG is no more used from this answer.
I want to create a test report/customize TestNG report to gave to development team. I used Hybrid Framework for creating the project and followed this tutorial.
Yes, you can customize the TestNG reports using Listeners and Reporters. Here is the link of documentation. It is not clear from a question what type of customization you want to do.
But I want to suggest better alternatives for reporting here. There are two most used libraries which generally used with Selenium.
Allure Test Report
Extent Report.
I have not used Allure test reports but it seems to be good and widely used in the community. I have had used Extent Reports in two projects and really happy with it. Anshoo Arora has done the remarkable job. Documentation is very good with lot of example & code snippet. I would highly recommend it.
To customize selenium TestNG report, you can use testng listeners.
ITestListener: Log Result/Screenshot on test pass/fail/skip.
IReporter: To generate html report from xml suite results and log.
But as an alternative you can use qaf-reporting.
It provides Detailed Live Reporting (Don`t need to wait for complete execution).
I know this is old thread, but these reports can be edited and custom reports can be made like below. I have also explained here how TestHTMLReporter can be edited . And if you would like to know , how index.html report is customized have a look here , where I have explained it in detail
With your customReport You'd have to implement IReporter , extend TestListenerAdapter and override generateReport method if you want to implement a custom TestHTMLReporter . For other reporters you may have to do things a bit differently but the concept will remain the same. You'd achieve custom 'TestHTMLReporter' like below .
Create a CustomReport.java file in your project and copy-paste the whole content of TestHTMLReporter.java , change the name of file in getOutputFile method and it would look like below
public class CustomReport extends TestListenerAdapter implements IReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites,
String outputDirectory) {
}
...
//paste the content of TestHTMLReporter.java here
...
...
Make sure all your imports are in place from TestHTMLReporter.java
Now, in this file change as per your requirement . For ex: if you'd like to add the end time of each of the test then at the correct place in generateTable method add the below snippet
// Test class
String testClass = tr.getTestClass().getName();
long testMillis = tr.getEndMillis();
String testMillisString = Long.toString(testMillis);
if (testClass != null) {
pw.append("<br>").append("Test class Name: ").append(testClass);
// this line to add end time in ms
pw.append("<br>").append("End Time(ms): ").append(testMillisString);
// Test name
String testName = tr.getTestName();
if (testName != null) {
pw.append(" (").append(testName).append(")");
}
Then you'll get like below
Now, You'll get two reports one with default and the other with your file name.
The only thing now remains is switching off the default reporting listeners, so you get only one report. For that you can follow this or you may search for solutions. Hope this helps

using Selenium: how to use output from one test as input to another test

I'm a Selenium n00b... it's clear how easy it is to run a test and verify a particular response, but how can I take a value from one response and use it in the next test?
an example might be a contact creation form...
type in name/email and click submit
response arrives with new ContactID
grab the ContactID that was returned and put it into "get" textbox and click "submit"
response arrives with contact details
verfy the name/email match the first set
how might I go about doing this in Selenium?
And now something completely different:
Now I understand when you say "test", you mean a single assertion within one test case. So you want to use a value returned from a request as input for another request in the same test case.
Assuming you use selenium ide: To do this, use one of the "store..." commands in selenium ide and store the value into a variable. The contactID can be found using a matching selector with the storeText command. For example:
command: storeText
target: selector for element containing contactId
value: contactId
Then, use variable substitution and the type command to insert that text somewhere else.
command: type
target: selector for target input box
value: ${contactId}
Hope this helps :)
(This answer is still correct I think if you interpret "test" as "test case". For another, totally different answer see below.)
You don't do this. Each test should be independent from all other tests. For your second test, just repeat the steps in the first test. This way, you can reproduce test success and failures in a reliable way.
If you have many tests which all start from a certain application state which requires many steps to reach, just write a private helper method to reach that state.
The alternative: All steps you describe can be put into a single test. There is no reason not to have several asserts in one test.

Logging Application Block-Microsoft Enterprise Library 4.1

In Logging Application Block in Logger.Write it takes event id as one of the parameter which is integer.So how to decide what should be passed as event id?
btw, do you really need to use the eventId? I think you can just pass the string you want to log:-
Logger.Write("SomeMessage");
EDIT :- I meant there should be another overload which takes just the string you want to write.
EDIT :- From here :-
EventId - a value you can use to
further categorise Log Entries
(defaults to 0 for a LogEntry and to 1
for a LogEntry implicitly created by
Logger.Write);
What we do is gather the different "stories" that you want to report on and then assign a sequence of event IDs to each of those stories. So in short, come up with a system that works for you and document it for future reference.