Apexon test automation framework provides test page concept in a best efficient way by which you can manipulate page navigation same as on actual web application under test. Once page get created page objects/functionalities can be used in any test case, makes code more reusable. The framework takes care of not only launching that page but the entire page hierarchy to reach that specific page. Furthermore it also checks that is page already active in browser? If so then it will continue from there, results in reduced execution time.
Following are two of the test cases that demonstrates
- Reusability of code
- Reduced execution time
- Less maintenance
As the class the derived from framework’s base class, test case developer only need to concentrate on writing the tests and not spend time on adjusting the underlying framework.
@Priority(value = 1) @Test(enabled = true, groups = {"BulkUpload", "Supplier", "Report"}, description = "TC4277: Verify that 'Upload Status Report' link is visible to buyer on 'Supplier Upload Status' page.") public void TC4277() { String jobid = context.getAttribute("upload.jobid.TC4277").toString(); UploadStatusPage statusPage = new UploadStatusPage(getSTB()); statusPage.launchPage(jobid); getSTB().assertElementPresent(UploadStatusPage.UPLOAD_STATUS_REPORT_LINK_LOC, "'View Report' link"); getSTB().verifyIsVisible(UploadStatusPage.UPLOAD_STATUS_REPORT_LINK_DIV_LOC, "View Report link"); }
Commands executed in selenium. You can see commands executed for the entire page hierarchy to reach that specific page.
getNewBrowserSession | *iehta | https://www.domainname.com/ | OK,6636575977794f15be1fd6bbdabc5642 |
setTimeout | 100000 | OK | |
setContext | TC4277 | OK | |
isTextPresent | 10560452 | OK,false | |
isElementPresent | //td[@class=’pageTitle’] | OK,false | |
isElementPresent | link=Suppliers | OK,false | |
isElementPresent | link=Home | OK,false | |
isElementPresent | link=Suppliers | OK,false | |
isTextPresent | Login | OK,true | |
isElementPresent | xpath=(//input[@name=’j_username’])[1] | OK,false | |
open | /aems/login.do | OK | |
waitForPageToLoad | 100000 | OK | |
isTextPresent | Home | OK,false | |
isTextPresent | Login | OK,true | |
isElementPresent | xpath=(//input[@name=’j_username’])[1] | OK,true | |
isTextPresent | Home | OK,false | |
waitForCondition | selenium.isElementPresent(“xpath=(//input[@name=’j_username’])[1]”) | 100000 | OK |
type | xpath=(//input[@name=’j_username’])[1] | xxx | OK |
type | xpath=(//input[@name=’j_password’])[1] | yyy | OK |
click | xpath=(//input[@type=’submit’])[1] | OK | |
waitForPageToLoad | 100000 | OK | |
click | link=Suppliers | OK | |
waitForPageToLoad | 100000 | OK | |
isElementPresent | link=Upload History | OK,true | |
click | link=Upload History | OK | |
waitForPageToLoad | 100000 | OK | |
isElementPresent | //table/tbody/tr[td/a[contains(text(),’10560452′)]][1]/td/a[contains(text(),’View’)] | OK,true | |
click | //table/tbody/tr[td/a[contains(text(),’10560452′)]][1]/td/a[contains(text(),’View’)] | OK | |
waitForPageToLoad | 100000 | OK | |
isElementPresent | link=View Report | OK,true | |
isVisible | //div[@id=’statusReportLink’] | OK,true |
Framework concept is based on page services so your page and related actions will be reusable from any test case. Thus test case becomes highly maintainable and utilize reusable test asset with proper modularity and semantic structure.
In case of sequential execution it will take advantage of sharing browser sessions between multiple test cases. No special coding or design required to run test in parallel, you just need to set parallel attribute’s appropriate value in configuration file (eg. false, Test, methods, classes) and framework will take care for providing thread safe browser sessions with maximum level of sharing browser session between multiple test cases. This will result in reducing time by parallel processing as well as by some level of sharing browser session(depends on configuration). You also can configure to run parallel in different browser (eg. iexplorer, firefox) with or without selenium grid.
Here is another test case, which get executed after above one. It will found the page loaded and get continued for test steps. Thus results in less execution time.
@Priority(value = 2) @Test(enabled = true, groups = {"BulkUpload", "Supplier", "Report"}, description = "Verify that application generates in-progress status bar during report execution.") public void TC4278() { String jobid = context.getAttribute("upload.jobid.TC4278").toString(); UploadStatusPage statusPage = new UploadStatusPage(getSTB()); statusPage.launchPage(jobid); getSTB().assertElementPresent(UploadStatusPage.UPLOAD_STATUS_REPORT_LINK_LOC, "'View Report' link"); getSTB().verifyIsVisible(UploadStatusPage.UPLOAD_STATUS_REPORT_LINK_DIV_LOC, "'View Report' link"); statusPage.clickUploadSatatusReportLink(); getSTB().verifyIsVisible (UploadStatusPage.INPROGRESS_STATUS_BAR_DIV_LOC, "In-progress status bar"); }
Selenium-Command | Parameter-1 | Parameter-2 | Res.RC |
setContext | TC4278 | OK | |
isTextPresent | 10560452 | OK,true | |
isElementPresent | //td[@class=’pageTitle’] | OK,true | |
getText | //td[@class=’pageTitle’] | OK,Supplier Upload Status | |
isTextPresent | 10560452 | OK,true | |
isElementPresent | link=View Report | OK,true | |
isVisible | //div[@id=’statusReportLink’] | OK,true | |
click | link=View Report | OK | |
isVisible | //div[@id=’statusReportProgress’] | OK,false |
When functionality changes only the specific test page file needs to be updated: if there is any change in page/ui of web application under test you need to update just in particular page rather than each and every test case, thus result in less maintenance.
Following page class illustrate how the navigation took place by derived page object. Whenever page’s launchPage method called framework will check for existence of page in browser if it is not loaded then it will call openPage method to open page from parent/launcher page (UploadHistoryPage in our case) Framework will call openPage method only if page is not loaded and parent is loaded. If parent is not loaded framework will call parent’s launch method.
public class UploadStatusPage extends BaseTestPage<UploadHistoryPage> { @Override protected void openPage(PageLocator locator) { parent.viewPostUploadResults(locator.getLocator()); } //method below check is supplier upload status page open and for given job? @Override public boolean isPageActive() { return pageLocator != null && pageLocator.getLocator() != null && selenium.isElementPresent("//td[@class='pageTitle']") && selenium.getText("//td[@class='pageTitle']").trim().equalsIgnoreCase( "Supplier Upload Status") && selenium.isTextPresent(pageLocator.getLocator()); } //overloaded method for simplicity public void launchPage(String fileNameOrJobID) { launchPage(new DefaultPageLocator(fileNameOrJobID)); } @Override protected void initParent() { parent = new UploadHistoryPage(stb); } //all page specific functionality goes here }
Generated Report displays:
- description of test case
- browser name
- duration
- selenium command log
- assertion/verification/information message Screens-shots for failure (also can configure for pass assertion/verification)
FAQ
Can I run each test without sharing browser session?
Yes, set property selenium.singletone=0
It will start new selenium session for each test. Still you can save execution time by configure to run methods in parallel
How to run test in parallel?
To run test in parallel you need to set parallel attribute appropriate value in configuration file. You can found configuration details in TestNG documentation.
Can I capture screenshot for passed assertion/verification?
Yes, set selenium.success.screenshots=1. It will automatically cupture screenshot and create link for pass messages.