From 5e1125d8fef0443e4af6f56332d502470fb1beb3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 29 Apr 2019 13:57:01 +0530 Subject: [PATCH 1/2] PRO-2230: Upload sample strategies file to Provar Marketplace --- labellocators/SFDCLightningEditFlow.java | 26 ++++++ pagestrategies/README.md | 14 ++++ pagestrategies/SFDCClassicNavigationTabs.java | 40 ++++++++++ pagestrategies/SFDCClassicSection.java | 26 ++++++ pagestrategies/SFDCLightningDetailsTab.java | 30 +++++++ pagestrategies/SFDCLightningDialog.java | 22 +++++ .../SFDCLightningNavigationTabs.java | 80 +++++++++++++++++++ pagestrategies/SFDCLightningPageSection.java | 25 ++++++ 8 files changed, 263 insertions(+) create mode 100644 labellocators/SFDCLightningEditFlow.java create mode 100644 pagestrategies/README.md create mode 100644 pagestrategies/SFDCClassicNavigationTabs.java create mode 100644 pagestrategies/SFDCClassicSection.java create mode 100644 pagestrategies/SFDCLightningDetailsTab.java create mode 100644 pagestrategies/SFDCLightningDialog.java create mode 100644 pagestrategies/SFDCLightningNavigationTabs.java create mode 100644 pagestrategies/SFDCLightningPageSection.java diff --git a/labellocators/SFDCLightningEditFlow.java b/labellocators/SFDCLightningEditFlow.java new file mode 100644 index 0000000..f434cfb --- /dev/null +++ b/labellocators/SFDCLightningEditFlow.java @@ -0,0 +1,26 @@ +package pagestrategies; + +import org.openqa.selenium.support.FindBy; + +import com.provar.core.testapi.annotations.LabelLocatorStrategy; +import com.provar.core.testapi.annotations.StrategyLocator; + +@LabelLocatorStrategy(title = "SF Lightning Edit Label", // Name that will uniquely identify strategy file in TB + priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order + // labelLocators xpaths will be appended to control locator to identify label + labelLocators = { + @StrategyLocator(name = "a", findBy = @FindBy(xpath = "label[contains(@class, 'label')]/span")), + @StrategyLocator(name = "b", findBy = @FindBy(xpath="a[contains(@class,'rowLink')]/div[contains(@class, 'middle')]/div[contains(@class, 'fields')]//ul/li//a")), + @StrategyLocator(name = "c", findBy = @FindBy(xpath = "span[contains(@class, 'label')]/span")), + @StrategyLocator(name = "d", findBy = @FindBy(xpath = "div/span[contains(@class, 'label')]")), + }, + // controlLocators xpaths are matched with current node and for correct match label xpath is appended to find the label locator. + // preceding should be true in case control is preceding label + controlLocators = { + @StrategyLocator(name = "input", findBy = @FindBy(xpath = "input[contains(@class, 'input')]")), + @StrategyLocator(name = "check", findBy = @FindBy(xpath="div[contains(@class,'left slds-float--left')]//label[contains(@class, 'slds-checkbox')]//span[contains(@class,'slds-checkbox--faux')]"), preceding = true), + @StrategyLocator(name = "radio", findBy = @FindBy(xpath="div/span[contains(@class, 'slds-radio--faux')]", preceding = true)), + @StrategyLocator(name = "link", findBy = @FindBy(xpath = "div[contains(@class,'uiMenu')]//a")), + }) +public class SFDCLightningEditFlow { +} diff --git a/pagestrategies/README.md b/pagestrategies/README.md new file mode 100644 index 0000000..734cde4 --- /dev/null +++ b/pagestrategies/README.md @@ -0,0 +1,14 @@ +# MarketPlace Strategy Files +Use this directory to submit your Block Strategy files. +We recommend you name them consistently according to the platform and application they are for. + +Refer to https://provartesting.com/help/testing-with-provar/page-objects/block-locator-strategies/ +for more information on creating Block Locators + +Example suggested filenames: + +SFDCLightningNavigationTab.java Salesforce Lightning Navigation Tabs +SFDCLightningDialogs.java Salesforce Lightning Dialogs +SFDCLightningPageSection.java Salesforce Lightning Page Sections +SFDCClassicNavigationTab.java Salesforce Classic Navigation Tabs +SFDCClassicPageSections.java Salesforce Classic Page Sections diff --git a/pagestrategies/SFDCClassicNavigationTabs.java b/pagestrategies/SFDCClassicNavigationTabs.java new file mode 100644 index 0000000..e909d72 --- /dev/null +++ b/pagestrategies/SFDCClassicNavigationTabs.java @@ -0,0 +1,40 @@ +package pagestrategies; + +import java.util.List; + +import org.openqa.selenium.By; +import org.openqa.selenium.SearchContext; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +import com.provar.core.model.base.api.IRuntimeBrowserContext; +import com.provar.core.model.base.api.IRuntimeConfiguration; +import com.provar.core.model.base.api.IRuntimeConnection; +import com.provar.core.model.base.api.PageStrategyType; +import com.provar.core.testapi.IPageStrategyActivator; +import com.provar.core.testapi.annotations.StrategyLocator; +import com.provar.core.testapi.annotations.TabLocatorStrategy; + +@TabLocatorStrategy(title="SF Classic Tab", // Name that will uniquely identify strategy file in TB +tabName ="ClassicTab2", // Default name for the block that is displayed while mapping in TB +priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order +// The Tab content is identified first based on contentLocators xpaths +contentLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class, 'bodyDiv brdPalette brandPrimary')]")), +}, +// If there is a match for content, then the header of the active tab is identified using headerLocators xpath. +headerLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//li[contains(@id, 'Tab') and not(contains(@id,'MoreTabs'))]")), +}, +// The labelLocators xpaths is appended to headerLocators for identifying the label of the Tab +labelLocators = { + @StrategyLocator(findBy = @FindBy(xpath="a/text()")), +}, +// To identify the currently active tab, appliesIf qualifier is used as not(appliesIf). During execution, findBy xpath is used to activate the Tab +activators = { + @StrategyLocator(findBy = @FindBy(xpath="a"), appliesIf = @FindBy(xpath="self::*[not(contains(@class, 'zen-active'))]")), +} +) +public class SFDCClassicNavigationTabs { + +} diff --git a/pagestrategies/SFDCClassicSection.java b/pagestrategies/SFDCClassicSection.java new file mode 100644 index 0000000..ed6fa24 --- /dev/null +++ b/pagestrategies/SFDCClassicSection.java @@ -0,0 +1,26 @@ +package pagestrategies; + +import org.openqa.selenium.support.FindBy; + +import com.provar.core.testapi.annotations.PageSectionLocatorStrategy; +import com.provar.core.testapi.annotations.StrategyLocator; + +@PageSectionLocatorStrategy(title="SF Classic Page Section",// Name that will uniquely identify strategy file in TB +sectionName ="{label}PageSection", // Default name for the block that is displayed while mapping in TB +priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order +// The page section are identified based on the sectionLocators xpaths. +sectionLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class, 'pbSubsection')]")), +}, +// If there is match for section, then its label is identified based on labelLocators xpath. +labelLocators = { + @StrategyLocator(findBy = @FindBy(xpath="preceding-sibling::div[contains(@class, 'pbSubheader')][1]//h3")), +}, +// While execution, first section is checked it is collapsed based on appliesIf xpath and to expand findBy xpath is used. +expanders = { + @StrategyLocator(findBy = @FindBy(xpath="//preceding-sibling::div[contains(@class, 'pbSubheader')][1]//img"), appliesIf = @FindBy(xpath="preceding-sibling::div[contains(@class, 'pbSubheader')][1]/img[contains(@class,'showListButton')]")), +} +) +public class SFDCClassicSection { +} + diff --git a/pagestrategies/SFDCLightningDetailsTab.java b/pagestrategies/SFDCLightningDetailsTab.java new file mode 100644 index 0000000..8532da2 --- /dev/null +++ b/pagestrategies/SFDCLightningDetailsTab.java @@ -0,0 +1,30 @@ +package pagestrategies; + +import org.openqa.selenium.support.FindBy; + +import com.provar.core.testapi.annotations.StrategyLocator; +import com.provar.core.testapi.annotations.TabLocatorStrategy; + +@TabLocatorStrategy(title="SF Lightning Nested Tab Testing", // Name that will uniquely identify strategy file in TB +tabName ="{label} Tabs", // Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value +priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order +// The Tab content is identified first based on contentLocators xpaths +contentLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class,'region-main')]//section[contains(@class,'tabs__content active')]/div[contains(@class, 'flexipageComponent')]")), +}, +// If there is a match for content, then the header of the active tab is identified using headerLocators xpath. +headerLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class, 'windowViewMode-normal') and contains(@class, 'active')]//li[contains(@class, 'tabs__item') and contains(@class, 'uiTabItem')]")), +}, +// The labelLocators xpaths is appended to headerLocators for identifying the label of the Tab +labelLocators = { + @StrategyLocator(findBy = @FindBy(xpath="a/@title")), +}, +// To identify the currently active tab, appliesIf qualifier is used as not(appliesIf). During execution, findBy xpath is used to activate the Tab +activators = { + @StrategyLocator(findBy = @FindBy(xpath="."), appliesIf = @FindBy(xpath="self::*[not(contains(@class, 'active'))]")), +} +) +public class SFDCLightningDetailsTab { + +} diff --git a/pagestrategies/SFDCLightningDialog.java b/pagestrategies/SFDCLightningDialog.java new file mode 100644 index 0000000..0c0a922 --- /dev/null +++ b/pagestrategies/SFDCLightningDialog.java @@ -0,0 +1,22 @@ +package pagestrategies; + +import org.openqa.selenium.support.FindBy; + +import com.provar.core.testapi.annotations.DialogLocatorStrategy; +import com.provar.core.testapi.annotations.StrategyLocator; + +@DialogLocatorStrategy(title="SF Lightning Dialog", // Name that will uniquely identify strategy file in TB +dialogName="LightningDialog",// Default name for the block that is displayed while mapping in TB +priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order +// The Dialog is identified based on the dialogLocators xpath. +dialogLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class,'slds-modal slds-fade-in-open')]")), +}, +// The labelLocators are optional for Dialog, If present in the strategy file, then the label is identified based on the the labelLocators xpath. +labelLocators = { + @StrategyLocator(findBy = @FindBy(xpath=".//div[contains(@class, 'slds-modal__header')]/h2")), +} +) +public class SFDCLightningDialog { + +} diff --git a/pagestrategies/SFDCLightningNavigationTabs.java b/pagestrategies/SFDCLightningNavigationTabs.java new file mode 100644 index 0000000..8436326 --- /dev/null +++ b/pagestrategies/SFDCLightningNavigationTabs.java @@ -0,0 +1,80 @@ +package pagestrategies; + +import java.util.List; + +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.SearchContext; + +import com.provar.core.model.base.api.IRuntimeBrowserContext; +import com.provar.core.model.base.api.IRuntimeConfiguration; +import com.provar.core.model.base.api.IRuntimeConnection; +import com.provar.core.model.base.api.PageStrategyType; +import com.provar.core.testapi.IPageStrategyActivator; +import com.provar.core.testapi.annotations.StrategyLocator; +import com.provar.core.testapi.annotations.TabLocatorStrategy; + +@TabLocatorStrategy(title="SF Lightning Tab", // Name that will uniquely identify strategy file in TB +tabName ="{label}LightningTab", // Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value +priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order +// The Tab content is identified first based on contentLocators xpaths +contentLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class, 'windowViewMode-normal') and contains(@class, 'oneContent')]")), +}, +// If there is a match for content, then the header of the active tab is identified using headerLocators xpath. +headerLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//one-app-nav-bar-item-root[contains(@class, 'slds-context-bar__item')]")), +}, +// The labelLocators xpaths is appended to headerLocators for identifying the label of the Tab +labelLocators = { + @StrategyLocator(findBy = @FindBy(xpath="a/@title")), +}, +// To identify the currently active tab, appliesIf qualifier is used as not(appliesIf). During execution, findBy xpath is used to activate the Tab +activators = { + @StrategyLocator(appliesIf = @FindBy(xpath="self::*[not(contains(@class, 'slds-is-active'))]"), findBy = @FindBy(xpath=".")), +} +) +// IPageStrategyActivator interface can be implemented for writing custom for activating the required Tab. This is required when it is not possible to activate the Tab with single click. +public class SFDCLightningNavigationTabs implements IPageStrategyActivator{ + + @Override + public boolean doActivateBlock(IRuntimeConfiguration runtimeConfiguration, IRuntimeConnection runtimeConnection, + IRuntimeBrowserContext browserContext, Object searchContext, Object blockFindBy, String label, + PageStrategyType strategyType) { + // Check if tab is active or not + By activeTabXpath = By.xpath("//one-app-nav-bar-item-root[contains(@class, 'slds-context-bar__item')][a/@title = '"+label+"'][self::*[not(contains(@class, 'slds-is-active'))]]"); + if(((SearchContext)searchContext).findElements(activeTabXpath).size() > 0) { + // First clicking on More tab + By moreXpath = By.xpath("//one-app-nav-bar-menu-button[a/span/text()='More']/a"); + List elems = ((SearchContext)searchContext).findElements(moreXpath); + if(elems.size() == 0) { + // you can write custom code here + } else { + elems.get(0).click(); + } + // Adding wait for Dropdown to appear + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // then clicking on required tab + By xpath1 = By.xpath("//one-app-nav-bar-menu-item[contains(@class, 'slds-dropdown__item')][a//span/text() = '"+label+"'][a/span]"); + WebElement activator = null; + elems = ((SearchContext)searchContext).findElements(xpath1); + if(elems.size() == 0) { + // you can write custom code here + } else { + activator = elems.get(0); + } + // Scrolling to element in dropdown + ((JavascriptExecutor)(browserContext.getWebDriver())).executeScript("arguments[0].scrollIntoViewIfNeeded();", activator); + activator.click(); + } + + return true; + } + +} diff --git a/pagestrategies/SFDCLightningPageSection.java b/pagestrategies/SFDCLightningPageSection.java new file mode 100644 index 0000000..4d0f064 --- /dev/null +++ b/pagestrategies/SFDCLightningPageSection.java @@ -0,0 +1,25 @@ +package pagestrategies; + +import org.openqa.selenium.support.FindBy; + +import com.provar.core.testapi.annotations.PageSectionLocatorStrategy; +import com.provar.core.testapi.annotations.StrategyLocator; + +@PageSectionLocatorStrategy(title="SF Page Section", // Name that will uniquely identify strategy file in TB +sectionName ="{label} PageSection",// Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value +priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order +// The content of the sections is identified by the sectionLocators xpath +sectionLocators = { + @StrategyLocator(findBy = @FindBy(xpath="//div[contains(@class, 'forcePageBlockSection')]")), +}, +// The labelLocators xpaths are evaluated relative to the section to determine the label of the section +labelLocators = { + @StrategyLocator(findBy = @FindBy(xpath="h3//span[contains(@class, '__section-header-title')]")), +}, +// The appliesIf xpath is used during execution to identify if we need to expand the section, if yes then click operation is performed on the element evaluated by findBy xpath. +expanders = { + @StrategyLocator(findBy = @FindBy(xpath="h3/button/lightning-icon"), appliesIf = @FindBy(xpath="self::div[not(contains(@class, 'slds-is-open'))]")), +} +) +public class SFDCLightningPageSection { +} From 5c79a108b80f4f7fc1cb136e2b81860f9c5dfa92 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 29 Apr 2019 14:03:09 +0530 Subject: [PATCH 2/2] PRO-2230: Upload sample strategies file to Provar Marketplace --- pagestrategies/SFDCClassicNavigationTabs.java | 2 +- pagestrategies/SFDCClassicSection.java | 4 ++-- pagestrategies/SFDCLightningDetailsTab.java | 4 ++-- pagestrategies/SFDCLightningNavigationTabs.java | 2 +- pagestrategies/SFDCLightningPageSection.java | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pagestrategies/SFDCClassicNavigationTabs.java b/pagestrategies/SFDCClassicNavigationTabs.java index e909d72..9903748 100644 --- a/pagestrategies/SFDCClassicNavigationTabs.java +++ b/pagestrategies/SFDCClassicNavigationTabs.java @@ -16,7 +16,7 @@ import com.provar.core.testapi.annotations.TabLocatorStrategy; @TabLocatorStrategy(title="SF Classic Tab", // Name that will uniquely identify strategy file in TB -tabName ="ClassicTab2", // Default name for the block that is displayed while mapping in TB +tabName ="{label} Tab", // Default name for the block that is displayed while mapping in TB priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order // The Tab content is identified first based on contentLocators xpaths contentLocators = { diff --git a/pagestrategies/SFDCClassicSection.java b/pagestrategies/SFDCClassicSection.java index ed6fa24..67b8f47 100644 --- a/pagestrategies/SFDCClassicSection.java +++ b/pagestrategies/SFDCClassicSection.java @@ -5,8 +5,8 @@ import com.provar.core.testapi.annotations.PageSectionLocatorStrategy; import com.provar.core.testapi.annotations.StrategyLocator; -@PageSectionLocatorStrategy(title="SF Classic Page Section",// Name that will uniquely identify strategy file in TB -sectionName ="{label}PageSection", // Default name for the block that is displayed while mapping in TB +@PageSectionLocatorStrategy(title="SF Classic Section",// Name that will uniquely identify strategy file in TB +sectionName ="{label} Section", // Default name for the block that is displayed while mapping in TB priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order // The page section are identified based on the sectionLocators xpaths. sectionLocators = { diff --git a/pagestrategies/SFDCLightningDetailsTab.java b/pagestrategies/SFDCLightningDetailsTab.java index 8532da2..7faaaee 100644 --- a/pagestrategies/SFDCLightningDetailsTab.java +++ b/pagestrategies/SFDCLightningDetailsTab.java @@ -5,8 +5,8 @@ import com.provar.core.testapi.annotations.StrategyLocator; import com.provar.core.testapi.annotations.TabLocatorStrategy; -@TabLocatorStrategy(title="SF Lightning Nested Tab Testing", // Name that will uniquely identify strategy file in TB -tabName ="{label} Tabs", // Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value +@TabLocatorStrategy(title="SF Lightning Details Tab", // Name that will uniquely identify strategy file in TB +tabName ="{label} Tab", // Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order // The Tab content is identified first based on contentLocators xpaths contentLocators = { diff --git a/pagestrategies/SFDCLightningNavigationTabs.java b/pagestrategies/SFDCLightningNavigationTabs.java index 8436326..d3d4733 100644 --- a/pagestrategies/SFDCLightningNavigationTabs.java +++ b/pagestrategies/SFDCLightningNavigationTabs.java @@ -17,7 +17,7 @@ import com.provar.core.testapi.annotations.TabLocatorStrategy; @TabLocatorStrategy(title="SF Lightning Tab", // Name that will uniquely identify strategy file in TB -tabName ="{label}LightningTab", // Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value +tabName ="{label} Tab", // Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order // The Tab content is identified first based on contentLocators xpaths contentLocators = { diff --git a/pagestrategies/SFDCLightningPageSection.java b/pagestrategies/SFDCLightningPageSection.java index 4d0f064..be58aac 100644 --- a/pagestrategies/SFDCLightningPageSection.java +++ b/pagestrategies/SFDCLightningPageSection.java @@ -5,8 +5,8 @@ import com.provar.core.testapi.annotations.PageSectionLocatorStrategy; import com.provar.core.testapi.annotations.StrategyLocator; -@PageSectionLocatorStrategy(title="SF Page Section", // Name that will uniquely identify strategy file in TB -sectionName ="{label} PageSection",// Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value +@PageSectionLocatorStrategy(title="SF Lightning Section", // Name that will uniquely identify strategy file in TB +sectionName ="{label} Section",// Default name for the block that is displayed while mapping in TB, {label} will get replaced with actual label value priority = Integer.MAX_VALUE, // In case of multiple matches locators will be displayed in priority order // The content of the sections is identified by the sectionLocators xpath sectionLocators = {