A personal repository of random information in compensation for a fatigued biological computer
TestNG & Selenium
_PageObjectTemplate.java
package testNG;
import org.openqa.selenium.WebDriver;
public class _PageObjectTemplate {
private final WebDriver driver;
public _PageObjectTemplate(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageItemGroup opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
/* ******************** Query State ********************* */
/* ******************** Asserts ********************* */
private void assertCommonElements() {
}
/* ******************** Page utilities ********************* */
/* ******************** Page Services ********************* */
}
xx
PageCommon.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageCommon {
/*
* Elements common to all Archway GDAP pages (once logged in)
*/
private final WebDriver driver;
public PageCommon(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageCommon opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
private static final String ROOTXPATH = "//div[@id='primary-links']//";
private static final String SELECTEDXPATH = ROOTXPATH + "li[contains(@class,'selected')]/child::";
private static final String JOBSXPATH = "a[span[.='Jobs']]";
private static final String SEARCHXPATH = "a[contains(.,'Search')]";
private static final String THESAURUSXPATH = "a[span[.='Thesaurus']]";
private static final String LEGISLATIONXPATH = "a[span[.='Legislation']]";
static By byArchwayLogo = By.xpath("//div[@class='archway-logo']");
By byJobsLink = By.xpath( ROOTXPATH + JOBSXPATH);
By byJobsSelected = By.xpath( SELECTEDXPATH + JOBSXPATH);
By bySearchLink = By.xpath( ROOTXPATH + SEARCHXPATH);
By bySearchSelected = By.xpath( SELECTEDXPATH + SEARCHXPATH);
By byThesaurusLink = By.xpath( ROOTXPATH + THESAURUSXPATH);
By byThesaurusSelected = By.xpath( SELECTEDXPATH + THESAURUSXPATH);
By byLegislationLink = By.xpath( ROOTXPATH + LEGISLATIONXPATH);
By byLegislationSelected = By.xpath( SELECTEDXPATH + LEGISLATIONXPATH);
By byLogoutLink = By.xpath( "//a[.='Logout']");
/* ******************** Query State ********************* */
/* ******************** Asserts ********************* */
public void assertCommonElements() {
GDAPCommon.report("PageCommon.assertCommonElements: asserting all common elements as assume no restrictions by rights as yet");
GDAPCommon.waitForElementVisibleBy(driver, byJobsLink);
GDAPCommon.waitForElementVisibleBy(driver, bySearchLink);
GDAPCommon.waitForElementVisibleBy(driver, byThesaurusLink);
GDAPCommon.waitForElementVisibleBy(driver, byLegislationLink);
GDAPCommon.waitForElementVisibleBy(driver, byLogoutLink);
}
public void assertJobsLinkSelected() {
GDAPCommon.waitForElementVisibleBy(driver, byJobsSelected);
}
/* ******************** Page Utilities ********************* */
/* ******************** Page Services ********************* */
public PageLogin logout() {
GDAPCommon.clickBy(driver, byLogoutLink);
return new PageLogin(driver);
}
}
xx
PageLogin.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageLogin {
private final WebDriver driver;
public PageLogin(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageLogin opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
private By byLoginEdit = By.id("username");
private By byPasswordEdit = By.xpath("//input[@id='password']");
private By byLogoutExistingChk = By.xpath("//input[@id='exceptionIfMaximumSessionsExceeded']");
private By byLoginButton = By.xpath("//button[@id='login']");
private By byBadCredentialsMessage = By.xpath("//span[contains(.,'username or password you entered is incorrect')]");
private By byExistingSessionMessage = By.xpath("//span[contains(.,'already logged into')]");
/* ******************** Asserts ********************* */
private void assertCommonElements() {
GDAPCommon.waitForElementVisibleBy(driver, byLoginEdit);
GDAPCommon.waitForElementVisibleBy(driver, byPasswordEdit);
GDAPCommon.waitForElementVisibleBy(driver, byLoginButton);
}
public void assertExistingSessionMessage() {
GDAPCommon.waitForElementVisibleBy(driver, byExistingSessionMessage);
}
public void assertBadCredentialsMessage() {
GDAPCommon.waitForElementVisibleBy(driver, byBadCredentialsMessage);
}
/* ******************** Page Utilities ********************* */
private void loginDo(String login, String password, boolean logoutExistingSessions) {
/**
* Logs into GDAP per the credentials supplied
* Login name supplied must not be already logged in elsewhere
* If the result is a failed login the parent test will fail
*
* @param login a valid username
* @param password a valid password for login
*/
//Reporter.log("loginDo U='" + login + "', P='" + password + "', Override existing session: " + (logoutExistingSessions) ? "true" : "false" + "<br>");
String str = (logoutExistingSessions) ? "true" : "false";
GDAPCommon.report("PageLogin.loginDo U='" + login + "', P='" + password + "', Override existing session: " + str);
GDAPCommon.clearAndEnterTextBy(driver, byLoginEdit, login);
GDAPCommon.clearAndEnterTextBy(driver, byPasswordEdit, password);
if (logoutExistingSessions) {
GDAPCommon.clickBy(driver, byLogoutExistingChk);
}
GDAPCommon.clickBy(driver, byLoginButton);
}
/* ******************** Page Services ********************* */
public void loginButFailOnBadCredentials(String login, String password) {
GDAPCommon.report("PageLogin.loginFailBadUserName");
loginDo(login, password, false);
GDAPCommon.waitForElementVisibleBy(driver, byBadCredentialsMessage);
}
public void loginButFailOnExistingSession(String login, String password) {
GDAPCommon.report("PageLogin.loginFailExistingSession");
loginDo(login, password, false);
GDAPCommon.waitForElementVisibleBy(driver, byLogoutExistingChk);
GDAPCommon.waitForElementVisibleBy(driver, byExistingSessionMessage);
}
public PageCommon login(String login, String password) {
GDAPCommon.report("PageLogin.login");
loginDo(login, password, false);
return new PageCommon(driver);
}
public PageCommon loginOverExistingSession(String login, String password) {
GDAPCommon.report("PageLogin.loginOverExistingSession");
loginDo(login, password, true);
return new PageCommon(driver);
}
}
xx
PageJob_List.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageJob_List {
private final WebDriver driver;
public PageJob_List(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageJob_List opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
private static final String ROOTXPATH = "//div[@class='jobs']";
private By byContainer = By.xpath(ROOTXPATH);
// JOBS NAVIGATION OPTIONS
private static final String ROOTNAVXPATH = ROOTXPATH + "//div[@class='subnav']";
private static final String SELECTEDXPATH = ROOTNAVXPATH + "//li[contains(@class,'selected')]/child::";
private static final String MYJOBSXPATH = ROOTNAVXPATH + "//a[span[.='My jobs']]";
private static final String FORREVIEWXPATH = ROOTNAVXPATH + "//a[span[.='For review']]";
private static final String JOBSEARCHXPATH = ROOTNAVXPATH + "//a[span[.='Job search']]";
By byMyJobsLink = By.xpath( ROOTNAVXPATH + MYJOBSXPATH);
By byMyJobsSelected = By.xpath( ROOTNAVXPATH + SELECTEDXPATH + MYJOBSXPATH);
By byForReviewLink = By.xpath( ROOTNAVXPATH + FORREVIEWXPATH);
By byReviewSelected = By.xpath( ROOTNAVXPATH + SELECTEDXPATH + FORREVIEWXPATH);
By byJobSearchLink = By.xpath( ROOTNAVXPATH + JOBSEARCHXPATH);
By byJobSearchSelected = By.xpath( ROOTNAVXPATH + SELECTEDXPATH + JOBSEARCHXPATH);
// JOB ACTIONS (Outside a selected job)
private static final String ROOTJOBACTIONSXPATH = ROOTXPATH + "//div[@class='actions']";
By byCreateJobBtn = By.xpath(ROOTJOBACTIONSXPATH + "//a[@id='create-job']");
// JOB ELEMENT PER EACH JOB STATUS BLOCK IE 'In Draft'
// Job list header by state
private static final String ROOTJOBLISTXPATH =
ROOTXPATH + "//div[contains(@class,'jobListHead')]";
private static final String ROOTJOBLISTXPATHINCOMPLETE =
ROOTXPATH + "//div[contains(@class,'jobListHead')"; // Note missing closing ']'
private static final String JOBLISTHEADERBYSTATE = ROOTJOBLISTXPATHINCOMPLETE + " and descendant::span[.='STATE']]/h4";
By byListHeader(GDAPCommon.JOBSTATES state) {
return By.xpath(JOBLISTHEADERBYSTATE.replaceAll("STATE", state.getText()));
}
// Job list by state including title
private static final String JOBLISTBYSTATE = ROOTJOBLISTXPATHINCOMPLETE + "and descendant::span[.='STATE']]/following-sibling::*";
By byList(GDAPCommon.JOBSTATES state) {
return By.xpath(JOBLISTBYSTATE.replaceAll("STATE", state.getText()));
}
// Job list by state excluding title
private static final String JOBLISTROWS = JOBLISTBYSTATE + "//tbody/tr";
By byRows(GDAPCommon.JOBSTATES state) {
return By.xpath(JOBLISTROWS.replaceAll("STATE", state.getText()));
}
// Specific job list rows
// target parameter:
// - ROW returns whole row, anything else returns target column
public enum COLUMNS {
ROW(""),
TITLE("//td[@class='title']/span"),
CREATED("//td[@class='created']/span"),
ARRIVED("//td[@class='arrived']/span"),
ENTITYCOUNT("//td[@class='entities']/span/span[1]"),
ITEMCOUNT("/td[@class='entities']/span/span[2]"),
FLAG("//td[@class='flag']/a"),
FLAGONLYIFSET("//td[@class='flag']/a/img[not(contains(@src,'unset'))]");
private String text;
private COLUMNS(String text){
this.text = text;
}
public String getText() {
return text;
}
}
By byRowByPosition(GDAPCommon.JOBSTATES state, int row, COLUMNS target) {
return By.xpath(JOBLISTROWS.replaceAll("STATE", state.getText()) + "[" + row + "]" + target.getText());
}
//private static final String JOBLISTROWSELECTED = "//tbody/tr[contains(@class,'selected')]";
//private By byRowSelected(GDAPCommon.JOBSTATES state, COLUMNS target) {
// return By.xpath(JOBLISTROWS.replaceAll("STATE", state.getText()) + JOBLISTROWSELECTED + target.getText());
//}
private static final String JOBLISTROWSELECTED = ROOTJOBLISTXPATH + "//tbody/tr[contains(@class,'selected')]";
By byRowSelected(COLUMNS target) {
return By.xpath(JOBLISTROWSELECTED + target.getText());
}
private static final String JOBLISTROWBYTITLE = "[td[@class='title' and descendant::span[text()='TITLE']]]";
By byRowByTitle(GDAPCommon.JOBSTATES state, String title, COLUMNS target) {
return By.xpath(JOBLISTROWS.replaceAll("STATE", state.getText()) + JOBLISTROWBYTITLE.replaceAll("TITLE", title) + target.getText());
}
/* ******************** Query State ********************* */
public boolean doesJobListHeaderExist(GDAPCommon.JOBSTATES state) {
/*
* Look across job states for a single selected job
*/
return GDAPCommon.isElementPresentBy(driver, byListHeader(state));
}
public int countJobsByState(GDAPCommon.JOBSTATES state) {
/*
* Counts jobs in the list per a specific job state
*/
GDAPCommon.report("PageJob_List.countJobsByState '" + state.getText() + "'");
expandJobList(state);
return GDAPCommon.getElementsCountBy(driver, byRows(state));
}
public boolean isAJobCurrentlySelected() {
/*
* Look across job states for a single selected job
*/
return GDAPCommon.isElementPresentBy(driver, byRowSelected(COLUMNS.ROW));
}
/* ******************** Asserts ********************* */
public void assertCommonElements() {
GDAPCommon.report("PageJob_List.assertCommonElements: only asserts containing elements as maybe no jobs");
GDAPCommon.waitForElementPresentBy(driver, byContainer);
}
public void assertElementsByRole(GDAPCommon.ROLES role) {
GDAPCommon.report("PageJob_List.assertElementsByRole: INCOMPLETE UNTIL ROLES DEFINED");
GDAPCommon.report("PageJob_List.assertElementsByRole: " + role.getText());
if (role == GDAPCommon.ROLES.EDITOR) {
GDAPCommon.waitForElementVisibleBy(driver, byMyJobsLink);
GDAPCommon.waitForElementVisibleBy(driver, byJobSearchLink);
}
if (role == GDAPCommon.ROLES.REVIEWER) {
GDAPCommon.waitForElementVisibleBy(driver, byForReviewLink);
GDAPCommon.waitForElementVisibleBy(driver, byJobSearchLink);
}
}
public void assertMyJobsLinkSelected() {
GDAPCommon.report("PageJob_List.assertMyJobsLinkSelected");
GDAPCommon.waitForElementVisibleBy(driver, byMyJobsSelected);
}
public void assertJobIsSelectedByStateAndTitle(GDAPCommon.JOBSTATES state, String title) {
GDAPCommon.report("PageJob_List.assertJobIsSelectedByStateAndTitle: '" + state.getText() + "', '" + title);
GDAPCommon.waitForElementByEqualsElementBy(driver, byRowByTitle(state, title, COLUMNS.ROW), byRowSelected(COLUMNS.ROW));
}
/* ******************** Page Utilities ********************* */
private void clickJobListHeader(GDAPCommon.JOBSTATES state) {
/*
* Click job list header
*/
GDAPCommon.report("PageJob_List.clickJobListHeader");
GDAPCommon.clickBy(driver, byListHeader(state));
}
/* ******************** Page Services ********************* */
public void expandJobList(GDAPCommon.JOBSTATES state) {
/*
* If a job list exists ensures its jobs are displayed
*/
GDAPCommon.report("PageJob_List.expandJobList '" + state.getText() + "'");
if (doesJobListHeaderExist(state)) {
if(GDAPCommon.isPresentElementInvisibleBy(driver, byRowByPosition(state, 1, COLUMNS.ROW))) {
clickJobListHeader(state);
}
}
}
public void clickJobRowByStateAndTitle(GDAPCommon.JOBSTATES state, String title) {
/*
* Click job row per state & title text
*/
GDAPCommon.report("PageJob_List.clickJobRowByStateAndTitle: '" + state.getText() + "', '" + title);
expandJobList(state);
GDAPCommon.clickBy(driver, byRowByTitle(state, title, COLUMNS.ROW));
assertJobIsSelectedByStateAndTitle(state, title);
}
public PageJob_Selected createJobAndVerify(String title, String loginName, String loginOffice) {
/*
* Creates a new job
*/
GDAPCommon.report("PageJob_List.createJobAndVerify: '" + title);
PageJob_Selected pageJobSelected = null;
boolean jobIsSelected = false;
String selectedJobNumber = "";
GDAPCommon.report("PageJob_List.createJobAndVerify: Get state of Job list before");
// get count of current draft jobs
int jobCountBefore = countJobsByState(GDAPCommon.JOBSTATES.INDRAFT);
GDAPCommon.report("PageJob_List.createJobAndVerify: Draft jobs count before: " + jobCountBefore);
GDAPCommon.report("PageJob_List.createJobAndVerify: Check for currently selected job");
if (jobCountBefore > 0) {
jobIsSelected = isAJobCurrentlySelected();
if (jobIsSelected) {
// Need a pageObject pageJobSelected
pageJobSelected = new PageJob_Selected(driver);
selectedJobNumber = pageJobSelected.getJobField(PageJob_Selected.ELEMENT.JOB_NUMBER);
GDAPCommon.report("PageJob_List.createJobAndVerify: Job selected: '" + selectedJobNumber + "'");
}
else {
GDAPCommon.report("PageJob_List.createJobAndVerify: No job selected: '" + selectedJobNumber + "'");
}
}
// create new job
GDAPCommon.report("PageJob_List.createJobAndVerify: Create job");
GDAPCommon.clickBy(driver, byCreateJobBtn);
// verify new job created & selected
if (jobIsSelected) {
pageJobSelected.assertJobIsNotSelectedByJobNumber(selectedJobNumber);
}
else {
pageJobSelected = new PageJob_Selected(driver);
}
GDAPCommon.report("PageJob_List.createJobAndVerify: Verify new job");
// verify job counts
int jobCountAfter = countJobsByState(GDAPCommon.JOBSTATES.INDRAFT);
if (jobCountAfter != (jobCountBefore + 1)) {
GDAPCommon.reportAndFail("PageJob_List.createJobAndVerify: FAIL: job count before: " + jobCountBefore +", after: " + jobCountAfter);
}
else {
GDAPCommon.reportAndFail("PageJob_List.createJobAndVerify: job count before: " + jobCountBefore +", after: " + jobCountAfter);
}
// verify new job defaults
pageJobSelected.assertNewJobMetadata(loginName, loginOffice);
// set new job title & verify
pageJobSelected.editJobTitleAndVerify(title);
return pageJobSelected;
}
}
xx
PageJob_Selected.java
package testNG;
import java.util.Date;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageJob_Selected {
private final WebDriver driver;
public PageJob_Selected(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageJob_Selected opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
private static final String ROOTXPATH = "//div[contains(@class,'selectedJob')]";
// Page is sectioned
private static final String SECTIONTITLEXPATH = ROOTXPATH + "//div[@class='job-title']";
private static final String SECTIONTOOLBARXPATH = ROOTXPATH + "//div[contains(@class,'btn-toolbar')]";
private static final String SECTIONFIELDSXPATH = ROOTXPATH + "//div[contains(@class,'basic-info')]";
@SuppressWarnings("unused")
private static final String SECTIONENTITIESXPATH = ROOTXPATH + "//*[@class='sectionHead' and text()='Entities']//following-sibling::*[1]";
private static final String SECTIONITEMGROUPSXPATH = ROOTXPATH + "//*[@class='sectionHead' and text()='Item Groups']//following-sibling::*[1]";
private static final String SECTIONBACKGROUNDINFOXPATH = ROOTXPATH + "//div[contains(@class,'background-info')]";
// SECTIONTOOLBARXPATH
// (Tool bar create entity button is in two equivalent parts)
private static final String BTNCREATEENTITYPARTTEXTXPATH = "//*[@id='create-entity']";
// target entity selection
private static final String BTNCREATEENTITYSELECTBYLABEL = SECTIONTOOLBARXPATH + "//ul[preceding-sibling::a[@id='create-entity']]//a[span[text()='ENTITY']]";
// SECTIONFIELDSXPATH
private static final String DISPLAYFIELDSPREFIX = SECTIONFIELDSXPATH + "//dd[preceding-sibling::dt[text()='";
private static final String DISPLAYFIELDSSUFFIX = "']][1]/span";
public static enum ELEMENT {
ROOT (ROOTXPATH),
JOB_TITLE (SECTIONTITLEXPATH + "//span"),
JOB_TITLEEDITABLE (SECTIONTITLEXPATH + "//input"),
JOB_TITLEEDITICON (SECTIONTITLEXPATH + "/descendant::a"),
TOOLBAR (SECTIONTOOLBARXPATH),
TOOLBAR_CREATEENTITYPARTTEXT (SECTIONTOOLBARXPATH + BTNCREATEENTITYPARTTEXTXPATH),
TOOLBAR_CREATEENTITYPARTDOWNARROW (SECTIONTOOLBARXPATH + BTNCREATEENTITYPARTTEXTXPATH + "/following-sibling::*"),
TOOLBAR_SENDFORREVIEW (SECTIONTOOLBARXPATH + "//*[contains(text(),'Send for review')]"),
TOOLBAR_DELETE (SECTIONTOOLBARXPATH + "//*[contains(text(),'Delete')]"),
TOOLBAR_UNASSIGN (SECTIONTOOLBARXPATH + "//*[contains(text(),'Unassign')]"),
JOB_NUMBER (DISPLAYFIELDSPREFIX + "Number" + DISPLAYFIELDSSUFFIX),
JOB_OWNER (DISPLAYFIELDSPREFIX + "Owner" + DISPLAYFIELDSSUFFIX),
JOB_OFFICE (DISPLAYFIELDSPREFIX + "Office" + DISPLAYFIELDSSUFFIX),
JOB_STATE (DISPLAYFIELDSPREFIX + "State" + DISPLAYFIELDSSUFFIX),
JOB_ARRIVED (DISPLAYFIELDSPREFIX + "Arrived" + DISPLAYFIELDSSUFFIX),
JOB_CREATED (DISPLAYFIELDSPREFIX + "Created" + DISPLAYFIELDSSUFFIX),
JOB_PRIORITYCHK (SECTIONFIELDSXPATH + "//dt[following-sibling::dd/label[text()='Prioritise']]/input"),
JOB_TYPEDROPDOWN (SECTIONFIELDSXPATH + "//dd[preceding-sibling::dt[text()='Type']][1]/select"),
JOB_BYNOTEREAD (SECTIONFIELDSXPATH + "//dd[preceding-sibling::dt[text()='Notes']]//div"),
JOB_BYNOTEDIT (SECTIONFIELDSXPATH + "//dd[preceding-sibling::dt[text()='Notes']]//textarea");
private String text;
private ELEMENT(String text){
this.text = text;
}
public String getText() {
return text;
}
private void checkXPathValidity() {
/*
* Checks XPaths for syntactical validity
* Useful as otherwise we have to wait for an XPath to be used before we find out it is incorrect
*/
ELEMENT[] elements = ELEMENT.values();
for (int i = 0; i < elements.length; i++) {
ELEMENT e = elements[i];
By by = By.xpath(e.getText());
}
}
};
static By byJobElement(ELEMENT jobElement) {
return By.xpath(jobElement.getText());
}
static By byCreateEntityOptionByLabel(GDAPCommon.ENTITIES entity) {
return By.xpath(BTNCREATEENTITYSELECTBYLABEL.replaceAll("ENTITY", entity.getText()));
}
// create entity drop down selections
private static final String SELECTEDJOBCREATEENTITYSELECTENTITY = SECTIONTOOLBARXPATH +
"//ul[preceding-sibling::a[@id='create-entity']]//a[span[text()='ENTITY']]";
By byCreateEntitySelect(GDAPCommon.ENTITIES entity) {
return By.xpath(SELECTEDJOBCREATEENTITYSELECTENTITY.replaceAll("ENTITY", entity.getText()));
}
// SECTIONENTITIESXPATH
// Not testing entities as yet
// SECTIONITEMGROUPSXPATH
By byItemGroupList = By.xpath(SECTIONITEMGROUPSXPATH);
private static final String ITEMGROUPROWSXPATH = SECTIONITEMGROUPSXPATH + "//tbody/tr";
By byItemGroupRows = By.xpath(ITEMGROUPROWSXPATH);
// Item group columns
public enum ITEMGROUPCOLUMNS {
ROW (""),
MOVE ("//td[@class='move']//a"),
TITLE ("//td[@class='title']//span"),
STATE ("//td[@class='state']//span");
private String text;
private ITEMGROUPCOLUMNS(String text){
this.text = text;
}
public String getText() {
return text;
}
}
private static final String ITEMGROUPROWBYTITLE = ITEMGROUPROWSXPATH + "[td[@class='title' and descendant::span[text()='TITLE']]]";
By byItemGroupRowByTitle(String title, ITEMGROUPCOLUMNS target) {
return By.xpath(ITEMGROUPROWBYTITLE.replaceAll("TITLE", title) + target.getText());
}
private static final String ITEMGROUPROWBYROW = ITEMGROUPROWSXPATH + "[ROW]";
By byItemGroupRowByRow(String row, ITEMGROUPCOLUMNS target) {
return By.xpath(ITEMGROUPROWBYROW.replaceAll("ROW", row) + target.getText());
}
// SECTIONBACKGROUNDINFOXPATH
// Comments & History
private static final String BACKGROUNDSELECTEDXPATH = SECTIONBACKGROUNDINFOXPATH + "//li[contains(@class, 'selected')]";
private static final String BACKGROUNDCOMMENTSXPATH = "//span[text()='Comments']";
private static final String BACKGROUNDHISTORYXPATH = "//span[text()='History']";
By byCommentTab = By.xpath(SECTIONBACKGROUNDINFOXPATH + BACKGROUNDCOMMENTSXPATH);
By byHistoryTab = By.xpath(SECTIONBACKGROUNDINFOXPATH + BACKGROUNDHISTORYXPATH);
By byCommentTabSelected = By.xpath(BACKGROUNDSELECTEDXPATH + BACKGROUNDCOMMENTSXPATH);
By byHistoryTabSelected = By.xpath(BACKGROUNDSELECTEDXPATH + BACKGROUNDHISTORYXPATH);
// Comment columns
public enum COMMENTCOLUMNS {
ROW (""),
DATE ("//td[@class='date']//span"),
NAME ("//td[@class='name']//span"),
COMMENTREAD ("//td[@class='comment']//span"),
COMMENTEDIT ("//td[@class='comment']//textarea"),
DELETE ("//td[@class='delete']//a");
private String text;
private COMMENTCOLUMNS(String text){
this.text = text;
}
public String getText() {
return text;
}
}
private static final String COMMENTBYCOMMENT = SECTIONBACKGROUNDINFOXPATH + "[td[@class='comment' and descendant::span[text()='COMMENT']]]";
By byCommentRowByComment(String comment, COMMENTCOLUMNS target) {
return By.xpath(COMMENTBYCOMMENT.replaceAll("COMMENT", comment) + target.getText());
}
private static final String COMMENTBYROW = SECTIONBACKGROUNDINFOXPATH + "[ROW]";
By byCommentRowByRow(String row, COMMENTCOLUMNS target) {
return By.xpath(COMMENTBYROW.replaceAll("ROW", row) + target.getText());
}
// HISTORY columns
public enum HISTORYCOLUMNS {
ROW (""),
DATE ("//td[@class='date']//span"),
NAME ("//td[@class='name']//span"),
OFFICE ("//td[@class='office']//span"),
EVENT ("//td[@class='event']//textarea");
private String text;
private HISTORYCOLUMNS(String text){
this.text = text;
}
public String getText() {
return text;
}
}
private static final String HISTORYBYEVENT = SECTIONBACKGROUNDINFOXPATH + "[td[@class='history' and descendant::span[text()='EVENT']]]";
By byHistoryRowByHistory(String event, HISTORYCOLUMNS target) {
return By.xpath(HISTORYBYEVENT.replaceAll("EVENT", event) + target.getText());
}
private static final String HISTORYBYROW = SECTIONBACKGROUNDINFOXPATH + "[ROW]";
By byHistoryRowByRow(String row, HISTORYCOLUMNS target) {
return By.xpath(HISTORYBYROW.replaceAll("ROW", row) + target.getText());
}
/* ******************** Query State ********************* */
public String getJobField(ELEMENT field) {
return GDAPCommon.getElementTextBy(driver, byJobElement(field));
}
public int countItemGroups() {
return GDAPCommon.getElementsCountBy(driver, byItemGroupRows);
}
/* ******************** Asserts ********************* */
public void assertCommonElements() {
GDAPCommon.report("PageJob_Selected.assertCommonElements");
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.ROOT));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_TITLE));
// Tool bar controls not validated as we may be read only on this job and don't know what renders based on rights yet
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_NUMBER));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_STATE));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_OWNER));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_ARRIVED));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_OFFICE));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_CREATED));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_PRIORITYCHK));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_TYPEDROPDOWN));
GDAPCommon.waitForElementVisibleBy(driver, byJobElement(ELEMENT.JOB_BYNOTEREAD));
GDAPCommon.waitForElementVisibleBy(driver, byCommentTab);
GDAPCommon.waitForElementVisibleBy(driver, byHistoryTab);
}
public void assertJobNumber(String text) {
GDAPCommon.report("PageJob_Selected.assertJobNumber");
GDAPCommon.waitForElementTextBy(driver, byJobElement(ELEMENT.JOB_NUMBER), text);
}
public void assertJobIsNotSelectedByJobNumber (String jobNumber) {
/*
* Ensures job is not selected
*/
GDAPCommon.report("PageJob_Selected.assertJobIsNotSelectedByJobNumber");
GDAPCommon.waitForElementNotTextBy(driver, byJobElement(ELEMENT.JOB_NUMBER), jobNumber);
}
public void assertNewJobMetadata(String loginName, String loginOffice) {
/*
* Assert user info, dates
*/
GDAPCommon.report("PageJob_Selected.assertNewJobMetadata");
GDAPCommon.waitForElementTextBy(driver, byJobElement(ELEMENT.JOB_STATE), GDAPCommon.JOBSTATES.INDRAFT.getText());
GDAPCommon.waitForElementDateBy(driver, byJobElement(ELEMENT.JOB_CREATED), new Date());
GDAPCommon.waitForElementDateBy(driver, byJobElement(ELEMENT.JOB_ARRIVED), new Date());
GDAPCommon.waitForElementTextBy(driver, byJobElement(ELEMENT.JOB_OWNER), loginName);
GDAPCommon.waitForElementTextBy(driver, byJobElement(ELEMENT.JOB_OFFICE), loginOffice);
}
/* ******************** Page Services ********************* */
public void editJobTitleAndVerify(String newTitle) {
/*
* Edit job title
* - A job must be selected
*/
GDAPCommon.report("PageJob_Selected.editJobTitleAndVerify '" + newTitle + "'");
GDAPCommon.report("PageJob_Selected.editJobTitleAndVerify: Old title: '" + GDAPCommon.getElementTextBy(driver, byJobElement(ELEMENT.JOB_TITLE)));
GDAPCommon.clickBy(driver, byJobElement(ELEMENT.JOB_TITLEEDITICON));
GDAPCommon.clearAndEnterTextBy(driver, byJobElement(ELEMENT.JOB_TITLEEDITABLE), newTitle);
GDAPCommon.clickHarmlessly(driver);
GDAPCommon.waitForElementTextBy(driver, byJobElement(ELEMENT.JOB_TITLE), newTitle);
GDAPCommon.report("PageJob_Selected.editJobTitleAndVerify: New title: '" + GDAPCommon.getElementTextBy(driver, byJobElement(ELEMENT.JOB_TITLE)));
}
public void createItemgroup(String newTitle) {
/*
* Create a new item group in a job
* - A job must be selected
*/
GDAPCommon.report("PageJob_Selected.createItemGroup: '" + newTitle + "'");
int itemgroupCountBefore = countItemGroups();
GDAPCommon.report("PageJob_Selected.createItemGroup: Itemgroup count before: " + itemgroupCountBefore);
GDAPCommon.clickBy(driver, byJobElement(ELEMENT.TOOLBAR_CREATEENTITYPARTDOWNARROW));
GDAPCommon.clickBy(driver, byCreateEntityOptionByLabel(GDAPCommon.ENTITIES.ITEMGROUP));
PageItemGroup_Header pageItemGroup = new PageItemGroup_Header(driver);
}
}
xx
PopupMoveEntity.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PopupMoveEntity {
private final WebDriver driver;
public PopupMoveEntity(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PopupMoveEntity opened");
};
/* ******************** Locators ********************* */
private static final String ROOTXPATH = "//div[div/h3/span[text()='Move to another Job']]";
By byPopup = By.xpath(ROOTXPATH);
By byClose = By.xpath(ROOTXPATH + "//a[@class='close']");
private static final String SELECTROOT = "//div[label[contains(text(),'Move to which job')]]";
private static final String SELECTABLEJOBS = SELECTROOT + "//option";
By bySelectableJobs = By.xpath(SELECTABLEJOBS);
private static final String SELECTIONBYTITLE = SELECTABLEJOBS + "[text()='TITLE']";
public By bySelectJobByTitle(String title) {
return By.xpath(SELECTROOT + SELECTIONBYTITLE.replaceAll("TITLE", title));
};
public By bySelectJobByRow(String row) {
return By.xpath(SELECTABLEJOBS + "[" + row + "]");
};
public By byCancel = By.xpath(ROOTXPATH + "//a[text()='Cancel']");
public By byMove = By.xpath(ROOTXPATH + "//a[text()='Move']");
public By byNoJobSelected = By.xpath(ROOTXPATH + "//div[contains(text(),'You must select a job to move to')]");
/* ******************** Asserts ********************* */
public void assertCommonElements() {
GDAPCommon.waitForElementVisibleBy(driver, byPopup);
GDAPCommon.waitForElementVisibleBy(driver, byClose);
GDAPCommon.waitForElementVisibleBy(driver, bySelectableJobs);
GDAPCommon.waitForElementVisibleBy(driver, byCancel);
GDAPCommon.waitForElementVisibleBy(driver, byMove);
}
public void assertNoJobSelectedMessage() {
GDAPCommon.waitForElementVisibleBy(driver, byNoJobSelected);
}
/* ******************** Actions ********************* */
public void selectJobByTitle(String title) {
GDAPCommon.clickBy(driver, bySelectJobByTitle(title));
}
public void selectJobByRow(String row) {
GDAPCommon.clickBy(driver, bySelectJobByRow(row));
}
public void clickClose() {
GDAPCommon.clickBy(driver, byClose);
}
public void clickMove() {
GDAPCommon.clickBy(driver, byMove);
}
}
xx
PageItemGroup_Header.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageItemGroup_Header {
private final WebDriver driver;
public PageItemGroup_Header(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageItemGroup opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
private static final String TITLEROOTXPATH = "//div[contains(@class,'item-group-title')]";
private static final String TOOLBARROOTXPATH = "//div[contains(@class,'toolbar-buttons')]";
private static final String COUNTSROOTXPATH = "//div[@class='item-summary-info']";
private static final String PAGINATIONROOTXPATH = "//div[@class='navigator']";
private static final String PAGEBYNUMBER = PAGINATIONROOTXPATH + "//a[span[text()='PAGE']]";
public static enum ELEMENT {
TITLECONTAINER (TITLEROOTXPATH),
TITLEREAD (TITLEROOTXPATH + "/descendant::span"),
TITLEEDIT (TITLEROOTXPATH + "/descendant::input"),
TITLEEDITICON (TITLEROOTXPATH + "/descendant::a"),
TOOLBARCONTAINER (TOOLBARROOTXPATH),
TOOLBAR_SAVE (TOOLBARROOTXPATH + "//a[contains(@class,'saveButton')]"),
TOOLBAR_BACK (TOOLBARROOTXPATH + "//a[descendant::*[contains(@class,'back-to-jobs')]]"),
TOOLBAR_SORT (TOOLBARROOTXPATH + "//a[.=' Sort']"),
TOOLBAR_CREATE (TOOLBARROOTXPATH + "//a[.=' Create']"),
TOOLBAR_IMPORT (TOOLBARROOTXPATH + "//a[.=' Import']"),
TOOLBAR_EXPORT (TOOLBARROOTXPATH + "//a[.=' Export']"),
TOOLBAR_FILL (TOOLBARROOTXPATH + "//a[.=' Fill']"),
TOOLBAR_MOVE (TOOLBARROOTXPATH + "//a[.=' Move']"),
TOOLBAR_READY (TOOLBARROOTXPATH + "//a[.=' Ready']"),
TOOLBAR_SELECTALL (TOOLBARROOTXPATH + "//a[.=' Select all']"),
TOOLBAR_SELECTBY (TOOLBARROOTXPATH + "//a[.=' Select by...']"),
TOOLBAR_CLEARSELECTION (TOOLBARROOTXPATH + "//a[.=' Clear selection']"),
TOOLBAR_FILTER (TOOLBARROOTXPATH + "//a[.=' Filter']"),
TOOLBAR_FILTERBY (TOOLBARROOTXPATH + "//a[.=' Filter by...']"),
TOOLBAR_CLEARFILTER (TOOLBARROOTXPATH + "//a[.=' Clear filter']"),
TOOLBAR_COMMENTS (TOOLBARROOTXPATH + "//a[.=' Comments']"),
COUNTSCONTAINER (COUNTSROOTXPATH),
COUNTTOTAL (COUNTSROOTXPATH + "//span[1]"),
COUNTFILTERED (COUNTSROOTXPATH + "//span[2]"),
COUNTSELECTED (COUNTSROOTXPATH + "//span[3]"),
PAGINGCONTAINER (PAGINATIONROOTXPATH),
PAGEFIRST (PAGINATIONROOTXPATH + "//a[@class='first']"),
PAGEPREVIOUS (PAGINATIONROOTXPATH + "//a[@class='prev']"),
PAGENEXT (PAGINATIONROOTXPATH + "//a[@class='next']"),
PAGELAST (PAGINATIONROOTXPATH + "//a[span[text()='PAGE']]"),
PAGEACTIVE (PAGINATIONROOTXPATH + "//li[@class='goto active']/a/span");
private String text;
private ELEMENT(String text){
this.text = text;
}
public String getText() {
return text;
}
}
static By byPagingByPageNumber(String pageNumber) {
return By.xpath(PAGEBYNUMBER.replaceAll("PAGE", pageNumber));
}
/* ******************** Query State ********************* */
/* ******************** Asserts ********************* */
private void assertCommonElements() {
}
/* ******************** Page Utilities ********************* */
/* ******************** Page Services ********************* */
}
xx
PageItemGroup_Items.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageItemGroup_Items {
private final WebDriver driver;
public PageItemGroup_Items(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageItemGroup_Items opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
/*
* With items in the Grid we first need to identify the row then the target
* element (if relevant) This also applies to an in-line expanded item detail
*/
private static final String ROOTXPATH = "//div[@class='results']";
private static final String HEADERSXPATH = ROOTXPATH + "//tr[@class='headers']";
private static final String ITEMDETAILCONTAINER = ROOTXPATH + "//tr[@class='detail']";
private static final String ITEMSUMMARYCONTAINER = ROOTXPATH + "//tr[@class='summary']";
private static final String ITEMSUMMARYCONTAINERINCOMPLETEWITHDESCENDANT =
ROOTXPATH + "//tr[@class='summary and descendant::'";
private static final String WORKBENCHCONTAINER = "//div[contains(@class,'item-edit-container')]";
private static final String WORKBENCHITEMCONTAINER =
WORKBENCHCONTAINER + "//div[contains(@class,'item-edit')]";
private static final String WORKBENCHITEMTABS = WORKBENCHITEMCONTAINER + "//div[contains(@class,'nav-tabs')]";
private static final String WORKBENCHITEMDETAIL = WORKBENCHITEMCONTAINER + "//div[contains(@class,'tab-content')]";
private static final String WORKBENCHTOOLBAR = WORKBENCHCONTAINER + "//div[contains(@class,'toolbar')]";
public static enum GRIDCOLUMNS {
/*
* Is not a complete XPath (just a snippet as is used in multiple ways)
* refer this.getAsValidXpath() for assembling into complete XPath fragment
*/
CHEVRON ("div[contains(@class,'chevron')"),
CHEVRONUP ("div[contains(@class,'chevron-right')"),
CHEVRONDOWN ("div[contains(@class,'chevron-down')"),
SELECTCHK ("input[@class='selectionCheckBox')"),
AGENCYRECID ("div[@class='agencyRecordIdentifier'"),
CODE ("div[@class='code'"),
TYPE ("div[contains(@class='item-type')"),
TITLE ("div[@class='title'"), YEARS("div[contains(@class='years')"),
SERIES ("div[@class='series'"), RESTRICTION("div[@class='restriction'"),
DESCRIPTION ("div[@class='description'"),
ACCESSION ("div[@class='accession'"),
STATE ("div[@class='state'"),
INGEST ("div[@class='ingest'");
private String text;
private GRIDCOLUMNS(String text) {
this.text = text;
}
public String getText() {
return text;
}
public String getAsValidXpath() {
return "//" + text + "]";
}
}
private String XPathItemContainerByRow(int rowNumber) {
/*
*
*/
return ITEMSUMMARYCONTAINER + "[" + rowNumber + "]";
}
private String XPathItemContainerByCellText(String text, GRIDCOLUMNS inColumn) {
/*
*
*/
return ITEMSUMMARYCONTAINERINCOMPLETEWITHDESCENDANT + inColumn.getText() + " and text()='" + text + "']]";
}
private By byItemContainerByRow(int rowNumber) {
/*
* Item Container element by Row number in table
*/
return By.xpath(XPathItemContainerByRow(rowNumber));
}
private By byItemContainerByCellText(String text, GRIDCOLUMNS inColumn) {
/*
* Item Container element by contents of a specific column Note: Doesn't
* work with Check boxes etc, just plain text type elements.
*/
return By.xpath(XPathItemContainerByCellText(text, inColumn));
}
private By byItemCellFromItemByRow(int rowNumber, GRIDCOLUMNS getColumn) {
/*
*
*/
return By.xpath(XPathItemContainerByRow(rowNumber) + getColumn.getAsValidXpath());
}
private By byItemCellFromItemByCellText(String text, GRIDCOLUMNS inColumn, GRIDCOLUMNS getColumn) {
/*
*
*/
return By.xpath(XPathItemContainerByCellText(text, inColumn) + getColumn.getAsValidXpath());
}
// Item tabs should be common to both in line view & workbench
private static final String TABVIEWCONTAINERXPATHINNER = "//ul[contains(@class,'nav-tabs')]";
public static enum ITEMTAB {
/*
* When used for in-line detail these require the item selector as a prefix
*/
GENERAL (TABVIEWCONTAINERXPATHINNER + "//a[descendant::span[.='General']]"),
RELATIONSHIPS (TABVIEWCONTAINERXPATHINNER + "//a[descendant::span[.='Relationships']]"),
REPOSITORY (TABVIEWCONTAINERXPATHINNER + "//a[descendant::span[.='Repository']]"),
RESTRICTIONS (TABVIEWCONTAINERXPATHINNER + "//a[descendant::span[.='Restrictions']]"),
DOCUMENTATION (TABVIEWCONTAINERXPATHINNER + "//a[descendant::span[.='Documentation']]");
private String text;
private ITEMTAB(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
// 20130128 Lets ignore In line detail view until we get affirmation it is in scope..
public static enum GRIDDETAIL {
/*
* Allows targeting fields in tabbed item view
* Although fields pop in out depending on the tab selected they are not children
* of the selected tab element in the DOM
*/
CODE ("div[@class='code'"),
TYPE ("div[contains(@class='item-type')"),
TITLEEDITABLE ("div[@class='title'"),
YEARS ("div[contains(@class='years')"),
SERIES ("div[@class='series'"),
RESTRICTION ("div[@class='restriction'"),
DESCRIPTION ("div[@class='description'"),
ACCESSION ("div[@class='accession'"),
STATE ("div[@class='state'"),
INGEST ("div[@class='ingest'");
private String text;
private GRIDDETAIL(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
/* ******************** Query State ********************* */
/* ******************** Asserts ********************* */
private void assertCommonElements() {
}
/* ******************** Page Utilities ********************* */
/* ******************** Page Services ********************* */
}
xx
PageItemGroup_WorkBench.java
package testNG;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class PageItemGroup_WorkBench {
private final WebDriver driver;
public PageItemGroup_WorkBench(WebDriver driver) {
this.driver = driver;
GDAPCommon.report("PageItemGroup_WorkBench opened");
assertCommonElements();
}
/* ******************** Locators ********************* */
// Tool-bar
// Tabs
// Fields
public static enum WORKBENCHFIELDS {
/*
* Rich text fields are special.. we need to identify the IFrame
*/
// 20130129 General tab
// Single
CODE ("//div[child::label[.='Code']]//div[@class='controls']//span"),
TITLEIFRAME ("//div[child::label[.='Title']]//div[@class='controls']//iframe"),
STARTYEARQUALIFIER ("//select[@name='years:startYear:qualifier']"),
STARTYEAR ("//input[@name='years:startYear:year']"),
ENDYEARQUALIFIER ("//select[@name='years:endYear:qualifier']"),
ENDYEAR ("//input[@name='years:endYear:year']"),
ADDITIONALDESCRIPTIONIFRAME ("//div[child::label[.='Title']]//div[@class='controls']//iframe"),
AGENCYDESCRIPTIONIFRAME ("//div[child::label[.='Title']]//div[@class='controls']//iframe"),
FUNCTIONDESCRIPTION ("//textarea[@name='functionDescription']"),
// multiple
ALTERNATIVETITLECONTAINER ("//fieldset[child::legend/span[.='Alternative titles']]//a[.='Add']"),
// 20130129 Relationships: don't touch until finalised
// 20130129 Repository
FORMAT ("//select[@name='format:field']"),
REPOSITORY ("//select[@name='repository:field']"),
CONTAINER ("//input[@name='container']"),
BOXNUMBER ("//input[@name='boxNumber']"),
ITEMNUMBER ("//input[@name='ItemNumber']"),
ITEMTYPE ("//div[child::label[.='Item type']]//div[@class='controls']//span"),
PRESENTATIONMANIFESTATION ("//select[@name='presentationManifestation']"),
RECORDGROUPREFERENCE ("//input[@name='rgReference']"),
SEPFLAG ("//select[@name='sepFlag']"),
SEPNUMBER ("//input[@name='sepNumber']"),
LEGACYLEVEL ("//select[@name='legacyLevel:field']"),
// 20130129 Restrictions
RESTRICTIONSTATUS ("//select[@name='restriction:status:field']"),
RESTRICTIONEXIRY ("//select[@name='restriction:expiry:field']"),
RESTRICTIONAUTOCHANGE ("//select[@name='restriction:autoChange:field']"),
PUBLICVIEWTYPE ("//select[@name='publicView:expiryTypes:field']"),
PUBLICVIEWAUTOCHANGE ("//select[@name='publicView:autoChange']"),
PUBLICVIEWSTATUS ("//select[@name='publicView:status']"),
PUBLICVIEWEXPIRYYEAR ("//input[@name='publicView:publicViewExpiryYear']"),
PUBLISHFLAG ("//select[@name='publishingFlag']"),
// 20130129 Documentation
RULESUSED ("//select[@name='rulesUsed:field']"),
DOCUMENTATIONSTANDARD ("//select[@name='documentationStandard:field']");
private String text;
private WORKBENCHFIELDS(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
// Alternative titles
//String ADD = "//fieldset[child::legend/span[.='Alternative titles']]//a[.='Add']";
/* ******************** Query State ********************* */
private void assertCommonElements() {
}
/* ******************** Page Utilities ********************* */
/* ******************** Page Services ********************* */
}
xx
xx