PageObjects

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