diff --git a/pom.xml b/pom.xml index 5581258..0b77cb5 100644 --- a/pom.xml +++ b/pom.xml @@ -70,19 +70,19 @@ ru.sbtqa.tag datajack - 1.2-SNAPSHOT + 1.2.0 jar ru.sbtqa.tag allure-helper - 1.1-SNAPSHOT + 1.1.0 jar ru.sbtqa.tag video-recorder - 1.1-SNAPSHOT + 1.0.5 jar @@ -91,6 +91,12 @@ 2.53.1 jar + + io.appium + java-client + 4.1.2 + jar + junit junit diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/DriverExtensions.java b/src/main/java/ru/sbtqa/tag/pagefactory/DriverExtensions.java deleted file mode 100644 index bc0a137..0000000 --- a/src/main/java/ru/sbtqa/tag/pagefactory/DriverExtensions.java +++ /dev/null @@ -1,407 +0,0 @@ -package ru.sbtqa.tag.pagefactory; - -import java.util.Set; -import org.junit.Assert; -import org.openqa.selenium.Alert; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.StaleElementReferenceException; -import org.openqa.selenium.TimeoutException; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import ru.sbtqa.tag.pagefactory.exceptions.GetValueException; -import ru.sbtqa.tag.pagefactory.exceptions.WaitException; -import ru.sbtqa.tag.qautils.managers.DateManager; - -public class DriverExtensions { - - private static final Logger LOG = LoggerFactory.getLogger(DriverExtensions.class); - - /** - * Get outer element text. Used for get text from checkboxes and radio buttons - * - * @param webElement TODO - * @return text of element - * @throws ru.sbtqa.tag.pagefactory.exceptions.GetValueException TODO - */ - public static String getElementValue(WebElement webElement) throws GetValueException { - String elementValue = "Cannot parse element"; - String elementId = webElement.getAttribute("id"); - - if (elementId == null) { - throw new GetValueException("Getting value is not support in element without id"); - } - - WebElement possibleTextMatcher = PageFactory.getWebDriver().findElement(By.xpath("//*[@id='" + elementId + "']/..")); - if (possibleTextMatcher.getText().isEmpty()) { - possibleTextMatcher = PageFactory.getWebDriver().findElement(By.xpath("//*[@id='" + elementId + "']/../..")); - if ("tr".equals(possibleTextMatcher.getTagName())) { - elementValue = possibleTextMatcher.getText(); - } - } else { - elementValue = possibleTextMatcher.getText(); - } - return elementValue; - } - - /** - * Wait until element present - * - * @param webElement Desired web element - */ - public static void waitUntilElementPresent(WebElement webElement) { - new WebDriverWait(PageFactory.getWebDriver(), PageFactory.getTimeOutInSeconds()). - until(ExpectedConditions.visibilityOf(webElement)); - } - - /** - * Wait until element present - * - * @param webElement Desired web element - * @param timeout Timeout in seconds - */ - public static void waitUntilElementPresent(WebElement webElement, int timeout) { - new WebDriverWait(PageFactory.getWebDriver(), timeout). - until(ExpectedConditions.visibilityOf(webElement)); - } - - /** - * Wait until element present - * - * @param webElement Desired web element - */ - public static void waitUntilElementToBeClickable(WebElement webElement) { - new WebDriverWait(PageFactory.getWebDriver(), PageFactory.getTimeOutInSeconds()). - until(ExpectedConditions.elementToBeClickable(webElement)); - } - - /** - * Wait until element present - * - * @param webElement Desired web element - * @param timeout Timeout in seconds - */ - public static void waitUntilElementToBeClickable(WebElement webElement, int timeout) { - new WebDriverWait(PageFactory.getWebDriver(), timeout). - until(ExpectedConditions.elementToBeClickable(webElement)); - } - - /** - * Wait until element is present and enable to check page prepare to work - * - * @param webElement Desired web element - */ - public static void waitUntilPagePrepared(WebElement webElement) { - try { - new WebDriverWait(PageFactory.getWebDriver(), PageFactory.getTimeOutInSeconds() / 2). - until(ExpectedConditions.visibilityOf(webElement)); - } catch (Exception | AssertionError e) { - LOG.debug("Element {} does not become visible after timeout", webElement, e); - PageFactory.getWebDriver().navigate().refresh(); - LOG.debug("Page refreshed"); - new WebDriverWait(PageFactory.getWebDriver(), PageFactory.getTimeOutInSeconds()). - until(ExpectedConditions.visibilityOf(webElement)); - } - } - - /** - * Wait for page prepared with javascript - * - * @param stopRecursion TODO - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO - */ - public static void waitForPageToLoad(boolean... stopRecursion) throws WaitException { - long timeoutTime = System.currentTimeMillis() + PageFactory.getTimeOut(); - while (timeoutTime > System.currentTimeMillis()) { - try { - if ("complete".equals((String) ((JavascriptExecutor) PageFactory.getWebDriver()).executeScript("return document.readyState"))) { - return; - } - sleep(1); - } catch (Exception | AssertionError e) { - LOG.debug("Page does not become to ready state", e); - PageFactory.getWebDriver().navigate().refresh(); - LOG.debug("Page refreshed"); - if ((stopRecursion.length == 0) || (stopRecursion.length > 0 && !stopRecursion[0])) { - waitForPageToLoad(true); - } - } - } - - throw new WaitException("Timed out after " + PageFactory.getTimeOutInSeconds() + " seconds waiting for preparedness of page"); - } - - /** - * Wait until element present - * - * @param by a {@link org.openqa.selenium.By} object. - * @return return appeared WebElement - */ - public static WebElement waitUntilElementAppearsInDom(By by) { - new WebDriverWait(PageFactory.getWebDriver(), PageFactory.getTimeOutInSeconds()) - .until(ExpectedConditions.presenceOfElementLocated(by)); - - return PageFactory.getWebDriver().findElement(by); - } - - /** - * Wait until element present - * - * @param by a {@link org.openqa.selenium.By} object. - * @param timeout timeout in seconds - * @return return appeared WebElement - */ - public static WebElement waitUntilElementAppearsInDom(By by, long timeout) { - new WebDriverWait(PageFactory.getWebDriver(), timeout) - .until(ExpectedConditions.presenceOfElementLocated(by)); - - return PageFactory.getWebDriver().findElement(by); - } - - /** - * Wait until element gone from dom - * - * @param timeout in milliseconds - * @param webElement a {@link org.openqa.selenium.WebElement} object. - */ - public static void waitUntilElementGoneFromDom(WebElement webElement, long timeout) { - Long start = DateManager.getCurrentTimestamp(); - while (DateManager.getCurrentTimestamp() < start + timeout) { - try { - if (!webElement.isDisplayed()) { - return; - } - } catch (NoSuchElementException | StaleElementReferenceException e) { - LOG.debug("There is no element {} in dom", webElement, e); - return; - } - sleep(1); - } - throw new NoSuchElementException("Timed out after " + timeout + " milliseconds waiting for web element '" + webElement.toString() + "' gone from DOM"); - } - - /** - * - * @param element a {@link org.openqa.selenium.WebElement} object. - */ - public static void waitUntilElementGetInvisible(WebElement element) { - new WebDriverWait(PageFactory.getWebDriver(), PageFactory.getTimeOutInSeconds()) - .until(ExpectedConditions.not(ExpectedConditions.visibilityOf(element))); - } - - /** - * - * @param webElement a {@link org.openqa.selenium.WebElement} object. - * @param timeout in milliseconds - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO - */ - public static void waitForTextInInputExists(WebElement webElement, long timeout) throws WaitException { - long timeoutTime = DateManager.getCurrentTimestamp() + timeout; - while (timeoutTime > DateManager.getCurrentTimestamp()) { - sleep(1); - if (!webElement.getAttribute("value").isEmpty()) { - return; - } - } - throw new WaitException("Timed out after '" + timeout + "' milliseconds waiting for existence of '" + webElement + "'"); - } - - /** - * Wait until specified text either appears, or disappears from page source - * - * @param text text to search in page source - * @param shouldTextBePresent boolean, self explanatory - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO - */ - public static void waitForTextPresenceInPageSource(String text, boolean shouldTextBePresent) throws WaitException { - long timeoutTime = System.currentTimeMillis() + PageFactory.getTimeOut(); - WebElement body = waitUntilElementAppearsInDom(By.tagName("body")); - while (timeoutTime > System.currentTimeMillis()) { - sleep(1); - if (body.getText().replaceAll("\\s+", "").contains(text.replaceAll("\\s+", "")) == shouldTextBePresent) { - return; - } - } - throw new WaitException("Timed out after '" + PageFactory.getTimeOutInSeconds()+ "' seconds waiting for presence of '" + text + "' in page source"); - } - - /** - *

- * waitForElementGetEnabled.

- * - * @param webElement a {@link org.openqa.selenium.WebElement} object. - * @param timeout a long. - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO - */ - public static void waitForElementGetEnabled(WebElement webElement, long timeout) throws WaitException { - long timeoutTime = DateManager.getCurrentTimestamp() + timeout; - while (timeoutTime > DateManager.getCurrentTimestamp()) { - sleep(1); - try { - if (webElement.isEnabled()) { - return; - } - } catch (Exception e) { - LOG.debug("Target element still not enable", e); - } - - } - throw new WaitException("Timed out after '" + timeout + "' milliseconds waiting for availability of '" + webElement + "'"); - } - - /** - * - * @param existingHandles TODO - * @param timeout TODO - * @return TODO - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO - */ - public static String findNewWindowHandle(Set existingHandles, int timeout) throws WaitException { - long timeoutTime = System.currentTimeMillis() + timeout; - - while (timeoutTime > System.currentTimeMillis()) { - Set currentHandles = PageFactory.getWebDriver().getWindowHandles(); - - if (currentHandles.size() != existingHandles.size() - || (currentHandles.size() == existingHandles.size() && !currentHandles.equals(existingHandles))) { - for (String currentHandle : currentHandles) { - if (!existingHandles.contains(currentHandle)) { - return currentHandle; - } - } - } - sleep(1); - } - - throw new WaitException("Timed out after '" + timeout + "' milliseconds waiting for new modal window"); - } - - /** - * - * @param existingHandles TODO - * @return TODO - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO - */ - public static String findNewWindowHandle(Set existingHandles) throws WaitException { - return findNewWindowHandle(existingHandles, PageFactory.getTimeOut()); - } - - /** - * Accept any alert regardless of its message - * - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException if alert didn't appear during timeout - */ - public static void acceptAlert() throws WaitException { - interactWithAlert("", true); - } - - /** - * Dismiss any alert regardless of its message - * - * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException if alert didn't appear during timeout - */ - public static void dismissAlert() throws WaitException { - interactWithAlert("", false); - } - - /** - * Wait for an alert with corresponding text (if specified). Depending on the decision, either accept it or decline - * If messageText is empty, text doesn't matter - * - * @param messageText text of an alert. If empty string is provided, it is being ignored - * @param decision true - accept, false - dismiss - * @throws WaitException in case if alert didn't appear during default wait timeout - */ - public static void interactWithAlert(String messageText, boolean decision) throws WaitException { - long timeoutTime = System.currentTimeMillis() + PageFactory.getTimeOut(); - - while (timeoutTime > System.currentTimeMillis()) { - try { - Alert alert = PageFactory.getWebDriver().switchTo().alert(); - if (!messageText.isEmpty()) { - Assert.assertEquals(alert.getText(), messageText); - } - if (decision) { - alert.accept(); - } else { - alert.dismiss(); - } - return; - } catch (Exception e) { - LOG.debug("Alert has not appeared yet", e); - } - sleep(1); - } - throw new WaitException("Timed out after '" + PageFactory.getTimeOutInSeconds() + "' seconds waiting for alert to accept"); - } - - /** - * Turn on element highlight - * - * @param webElement TODO - * @return initial element style - */ - public static String highlightElementOn(WebElement webElement) { - try { - JavascriptExecutor js = (JavascriptExecutor) PageFactory.getWebDriver(); - String style = (String) js.executeScript("return arguments[0].style.border", webElement); - js.executeScript("arguments[0].style.border='3px solid red'", webElement); - return style; - } catch (Exception e) { - LOG.warn("Something went wrong with element highlight", e); - return null; - } - } - - /** - * Turn off element highlight - * - * @param webElement TODO - * @param style element style to set - */ - public static void highlightElementOff(WebElement webElement, String style) { - if (style == null) { - return; - } - try { - JavascriptExecutor js = (JavascriptExecutor) PageFactory.getWebDriver(); - js.executeScript("arguments[0].style.border='" + style + "'", webElement); - } catch (Exception e) { - LOG.debug("Something went wrong with element highlight", e); - } - } - - /** - * - * @param text a {@link java.lang.String} object. - * @param timeout a {int} object. wait text during sec period - * @return true if exists - */ - public static boolean checkElementWithTextIsPresent(String text, int timeout) { - try { - new WebDriverWait(PageFactory.getWebDriver(), timeout) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), '" + text + "')]"))); - return true; - } catch (TimeoutException e) { - LOG.debug("Element with text {} is not located on page", text, e); - return false; - } - } - - /** - * - * @param sec a int. - */ - private static void sleep(int sec) { - try { - Thread.sleep(sec * 1000L); - } catch (InterruptedException e) { - LOG.warn("Error while thread is sleeping", e); - Thread.currentThread().interrupt(); - } - } -} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/Page.java b/src/main/java/ru/sbtqa/tag/pagefactory/Page.java index 9659f2e..00d8a66 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/Page.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/Page.java @@ -1,24 +1,47 @@ package ru.sbtqa.tag.pagefactory; +import static java.lang.String.format; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.reflect.MethodUtils; import org.junit.Assert; import org.openqa.selenium.By; import org.openqa.selenium.InvalidElementStateException; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebElement; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.Select; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.sbtqa.tag.allurehelper.ParamsHelper; import ru.sbtqa.tag.cucumber.TagCucumber; import ru.sbtqa.tag.datajack.Stash; import ru.sbtqa.tag.pagefactory.annotations.ActionTitle; import ru.sbtqa.tag.pagefactory.annotations.ActionTitles; +import ru.sbtqa.tag.pagefactory.annotations.ElementTitle; +import ru.sbtqa.tag.pagefactory.annotations.PageEntry; +import ru.sbtqa.tag.pagefactory.annotations.RedirectsTo; +import ru.sbtqa.tag.pagefactory.annotations.ValidationRule; +import ru.sbtqa.tag.pagefactory.exceptions.ElementDescriptionException; +import ru.sbtqa.tag.pagefactory.exceptions.ElementNotFoundException; +import ru.sbtqa.tag.pagefactory.exceptions.FactoryRuntimeException; import ru.sbtqa.tag.pagefactory.exceptions.PageException; +import ru.sbtqa.tag.pagefactory.exceptions.PageInitializationException; import ru.sbtqa.tag.pagefactory.exceptions.WaitException; +import ru.sbtqa.tag.pagefactory.extensions.DriverExtension; +import ru.sbtqa.tag.pagefactory.extensions.WebExtension; import ru.sbtqa.tag.qautils.errors.AutotestError; import ru.sbtqa.tag.qautils.i18n.I18N; import ru.sbtqa.tag.qautils.i18n.I18NRuntimeException; @@ -28,28 +51,6 @@ import ru.yandex.qatools.htmlelements.element.HtmlElement; import ru.yandex.qatools.htmlelements.element.TypifiedElement; -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import java.util.Arrays; -import java.util.Map; -import org.openqa.selenium.StaleElementReferenceException; -import org.slf4j.Logger; -import ru.sbtqa.tag.pagefactory.annotations.ElementTitle; -import ru.sbtqa.tag.pagefactory.annotations.PageEntry; -import ru.sbtqa.tag.pagefactory.annotations.RedirectsTo; -import ru.sbtqa.tag.pagefactory.annotations.ValidationRule; -import ru.sbtqa.tag.pagefactory.exceptions.ElementDescriptionException; -import ru.sbtqa.tag.pagefactory.exceptions.ElementNotFoundException; -import ru.sbtqa.tag.pagefactory.exceptions.FactoryRuntimeException; -import ru.sbtqa.tag.pagefactory.exceptions.PageInitializationException; - /** * Base page object class. Contains basic actions with elements, search methods */ @@ -122,10 +123,10 @@ public void clickElementByTitle(String elementTitle) throws PageException { WebElement webElement; try { webElement = getElementByTitle(elementTitle); - DriverExtensions.waitForElementGetEnabled(webElement, PageFactory.getTimeOut()); + DriverExtension.waitForElementGetEnabled(webElement, PageFactory.getTimeOut()); } catch (NoSuchElementException | WaitException e) { LOG.warn("Failed to find element by title {}", elementTitle, e); - webElement = DriverExtensions.waitUntilElementAppearsInDom(By.partialLinkText(elementTitle)); + webElement = DriverExtension.waitUntilElementAppearsInDom(By.partialLinkText(elementTitle)); } clickWebElement(webElement); } @@ -139,7 +140,7 @@ public void clickElementByTitle(String elementTitle) throws PageException { @ActionTitle("press.key") public void pressKey(String keyName) { Keys key = Keys.valueOf(keyName.toUpperCase()); - Actions actions = new Actions(PageFactory.getWebDriver()); + Actions actions = PageFactory.getActions(); actions.sendKeys(key).perform(); Core.addToReport(keyName, " is pressed"); } @@ -156,7 +157,7 @@ public void pressKey(String keyName) { @ActionTitle("press.key") public void pressKey(String keyName, String elementTitle) throws PageException { Keys key = Keys.valueOf(keyName.toUpperCase()); - Actions actions = new Actions(PageFactory.getWebDriver()); + Actions actions = PageFactory.getActions(); actions.moveToElement(getElementByTitle(elementTitle)); actions.click(); actions.sendKeys(key); @@ -265,7 +266,7 @@ public void select(WebElement webElement, String option, MatchStrategy strategy) + " content.push(options[i].text)" + "}" + "return content"; - List options = (ArrayList) ((JavascriptExecutor) PageFactory.getWebDriver()). + List options = (ArrayList) ((JavascriptExecutor) PageFactory.getDriver()). executeScript(jsString, webElement); boolean isSelectionMade = false; @@ -304,7 +305,7 @@ public void select(WebElement webElement, String option, MatchStrategy strategy) */ @ActionTitle("accept.alert") public void acceptAlert(String text) throws WaitException { - DriverExtensions.interactWithAlert(text, true); + DriverExtension.interactWithAlert(text, true); } /** @@ -316,7 +317,7 @@ public void acceptAlert(String text) throws WaitException { */ @ActionTitle("dismiss.alert") public void dismissAlert(String text) throws WaitException { - DriverExtensions.interactWithAlert(text, false); + DriverExtension.interactWithAlert(text, false); } /** @@ -329,7 +330,7 @@ public void dismissAlert(String text) throws WaitException { */ @ActionTitle("text.appears.on.page") public void assertTextAppears(String text) throws WaitException { - DriverExtensions.waitForTextPresenceInPageSource(text, true); + WebExtension.waitForTextPresenceInPageSource(text, true); } /** @@ -340,7 +341,7 @@ public void assertTextAppears(String text) throws WaitException { */ @ActionTitle("text.absent.on.page") public void assertTextIsNotPresent(String text) { - DriverExtensions.waitForTextPresenceInPageSource(text, false); + WebExtension.waitForTextPresenceInPageSource(text, false); } /** @@ -356,7 +357,7 @@ public void assertTextIsNotPresent(String text) { @ActionTitle("modal.window.with.text.appears") public void assertModalWindowAppears(String text) throws WaitException { try { - String popupHandle = DriverExtensions.findNewWindowHandle((Set) Stash.getValue("beforeClickHandles")); + String popupHandle = WebExtension.findNewWindowHandle((Set) Stash.getValue("beforeClickHandles")); if (null != popupHandle && !popupHandle.isEmpty()) { PageFactory.getWebDriver().switchTo().window(popupHandle); } @@ -533,7 +534,7 @@ public boolean checkValuesAreNotEqual(String text, WebElement webElement) { , @ActionTitle("check.text.visible")}) public void checkElementWithTextIsPresent(String text) { - if (!DriverExtensions.checkElementWithTextIsPresent(text, PageFactory.getTimeOutInSeconds())) { + if (!DriverExtension.checkElementWithTextIsPresent(text, PageFactory.getTimeOutInSeconds())) { throw new AutotestError("Text '" + text + "' is not present"); } } diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/PageFactory.java b/src/main/java/ru/sbtqa/tag/pagefactory/PageFactory.java index beb2e55..7f07fda 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/PageFactory.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/PageFactory.java @@ -1,39 +1,18 @@ package ru.sbtqa.tag.pagefactory; -import java.io.File; -import java.io.IOException; +import io.appium.java_client.AppiumDriver; import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; import java.util.HashMap; import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import net.lightbody.bmp.BrowserMobProxy; -import net.lightbody.bmp.BrowserMobProxyServer; -import net.lightbody.bmp.client.ClientUtil; -import org.apache.commons.lang3.SystemUtils; -import org.openqa.selenium.Alert; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.Proxy; import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.firefox.FirefoxDriver; -import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.remote.CapabilityType; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.remote.UnreachableBrowserException; -import org.openqa.selenium.safari.SafariDriver; import org.openqa.selenium.support.pagefactory.FieldDecorator; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import ru.sbtqa.tag.pagefactory.exceptions.UnsupportedBrowserException; -import ru.sbtqa.tag.pagefactory.support.DesiredCapabilitiesParser; +import ru.sbtqa.tag.pagefactory.drivers.TagMobileDriver; +import ru.sbtqa.tag.pagefactory.drivers.TagWebDriver; +import ru.sbtqa.tag.pagefactory.exceptions.FactoryRuntimeException; +import ru.sbtqa.tag.pagefactory.support.Environment; import ru.sbtqa.tag.qautils.properties.Props; import ru.sbtqa.tag.videorecorder.VideoRecorder; @@ -41,211 +20,58 @@ public class PageFactory { private static final Logger LOG = LoggerFactory.getLogger(PageFactory.class); - private static WebDriver webDriver; + private static final Map, Map> PAGES_REPOSITORY = new HashMap<>(); + private static Actions actions; - private static PageWrapper PageFactoryCore; + private static PageWrapper PageWrapper; private static VideoRecorder videoRecorder; - private static BrowserMobProxy proxy; // for use proxy, use Props proxy.enable = true - private static final Map, Map> PAGES_REPOSITORY = new HashMap<>(); + private static boolean aspectsDisabled = false; - private static final String PAGES_PACKAGE = Props.get("webdriver.pages.package"); + private static final String ENVIRONMENT = Props.get("driver.environment"); + private static final String INITIAL_URL = Props.get("driver.url"); + private static final String PAGES_PACKAGE = Props.get("page.package"); + private static final String TIMEOUT = Props.get("page.load.timeout"); private static final String BROWSER_NAME = Props.get("browser.name"); - private static final String TIMEOUT = Props.get("webdriver.page.load.timeout"); - private static final String INITIAL_URL = Props.get("webdriver.url"); - private static final int ATTEMPTS_TO_START_WEBDRIVER = Integer.parseInt(Props.get("webdriver.create.attempts", "3")); - - private static final String WEBDRIVER_PATH = "src/test/resources/webdrivers/"; - - private static boolean aspectsDisabled = false; + + private static final String ENVIRONMENT_WEB = "web"; + private static final String ENVIRONMENT_MOBILE = "mobile"; - /** - *

- * Getter for the field webDriver.

- * - * @return a {@link org.openqa.selenium.WebDriver} object. - */ public static WebDriver getWebDriver() { - if (null == webDriver) { - if (Boolean.valueOf(Props.get("video.enable"))) { - VideoRecorder.getInstance().startRecording(); - } - - for (int i = 1; i <= ATTEMPTS_TO_START_WEBDRIVER; i++) { - LOG.info("Attempt #" + i + " to start web driver"); - try { - createWebDriver(); - break; - } catch (UnreachableBrowserException e) { - LOG.warn("Failed to create web driver. Attempt number {}", i, e); - if (null != webDriver) { - // Don't dispose when driver is already null, cus it causes new driver creation at Init.getWebDriver() - dispose(); - } - } catch (UnsupportedBrowserException e) { - LOG.error("Failed to create web driver", e); - break; - } - } - } - return webDriver; + return getDriver(); } - private static void createWebDriver() throws UnsupportedBrowserException { - DesiredCapabilities capabilities = new DesiredCapabilitiesParser().parse(); - - if (Props.get("webdriver.remote.host").isEmpty()) { - - //Local proxy available on local webdriver instances only - if (!Props.get("proxy.enable").isEmpty()) { - setProxy(new BrowserMobProxyServer()); - proxy.start(0); - Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); - capabilities.setCapability(CapabilityType.PROXY, seleniumProxy); - } - switch (BROWSER_NAME) { - case "Firefox": - capabilities.setBrowserName("firefox"); - setWebDriver(new FirefoxDriver(capabilities)); - break; - case "Safari": - capabilities.setBrowserName("safari"); - setWebDriver(new SafariDriver(capabilities)); - break; - case "Chrome": - File chromeDriver = new File(WEBDRIVER_PATH + "chromedriver.exe"); - System.setProperty("webdriver.chrome.driver", chromeDriver.getAbsolutePath()); - capabilities.setBrowserName("chrome"); - setWebDriver(new ChromeDriver(capabilities)); - break; - case "Opera": - throw new UnsupportedOperationException("Opera browser is not supported yet."); - case "IE": - File IEdriver = new File(WEBDRIVER_PATH + "IEDriverServer.exe"); - System.setProperty("webdriver.ie.driver", IEdriver.getAbsolutePath()); - capabilities.setBrowserName("internet explorer"); - setWebDriver(new InternetExplorerDriver(capabilities)); - break; - default: - throw new UnsupportedBrowserException("'" + BROWSER_NAME + "' is not supported yet"); - } - } else { - - switch (BROWSER_NAME) { - case "Firefox": - capabilities.setBrowserName("firefox"); - break; - case "Safari": - capabilities.setBrowserName("safari"); - break; - case "Chrome": - File chromeDriver = new File(WEBDRIVER_PATH + "chromedriver.exe"); - System.setProperty("webdriver.chrome.driver", chromeDriver.getAbsolutePath()); - capabilities.setBrowserName("chrome"); - break; - case "Opera": - throw new UnsupportedOperationException("Opera browser supported as Chrome So change config to chrome."); - case "IE": - File IEdriver = new File(WEBDRIVER_PATH + "IEDriverServer.exe"); - System.setProperty("webdriver.ie.driver", IEdriver.getAbsolutePath()); - capabilities.setBrowserName("internet explorer"); - break; - default: - throw new UnsupportedBrowserException("'" + BROWSER_NAME + "' is not supported yet"); - } - try { - URL remoreUrl = new URL("http://" + Props.get("webdriver.remote.host") + ":4444/wd/hub"); - setWebDriver(new RemoteWebDriver(remoreUrl, capabilities)); - } catch (MalformedURLException e) { - LOG.error("Can not parse remote url. Check webdriver.remote.host property"); - } + public static AppiumDriver getMobileDriver() { + return (AppiumDriver) getDriver(); + } + + public static WebDriver getDriver() { + switch (getEnvironment()) { + case WEB: + return TagWebDriver.getDriver(); + case MOBILE: + return TagMobileDriver.getDriver(); + default: + throw new FactoryRuntimeException("Failed to get driver"); } - webDriver.manage().timeouts().pageLoadTimeout(getTimeOutInSeconds(), TimeUnit.SECONDS); - webDriver.manage().window().maximize(); - webDriver.get(INITIAL_URL); } - /** - * - */ public static void dispose() { - try { - LOG.info("Checking any alert opened"); - WebDriverWait alertAwaiter = new WebDriverWait(webDriver, 2); - alertAwaiter.until(ExpectedConditions.alertIsPresent()); - Alert alert = webDriver.switchTo().alert(); - LOG.info("Got an alert: " + alert.getText() + "\n Closing it."); - alert.dismiss(); - } catch (WebDriverException e) { - LOG.debug("No alert opened. Closing webdriver.", e); + switch (getEnvironment()) { + case WEB: + TagWebDriver.dispose(); + break; + case MOBILE: + TagMobileDriver.dispose(); + break; + default: + throw new FactoryRuntimeException("Failed to dispose"); } - - Set windowHandlesSet = webDriver.getWindowHandles(); - try { - if (windowHandlesSet.size() > 1) { - for (String winHandle : windowHandlesSet) { - webDriver.switchTo().window(winHandle); - ((JavascriptExecutor) webDriver).executeScript( - "var objWin = window.self;" - + "objWin.open('','_self','');" - + "objWin.close();"); - } - } - } catch (Exception e) { - LOG.warn("Failed to kill all of the iexplore windows", e); - } - - try { - if ("IE".equals(BROWSER_NAME) - && Boolean.parseBoolean(Props.get("browser.ie.killOnDispose", "true"))) { - // Kill IE by Windows means instead of webdriver.quit() - Runtime.getRuntime().exec("taskkill /f /im iexplore.exe").waitFor(); - Runtime.getRuntime().exec("taskkill /f /im IEDriverServer.exe").waitFor(); - } else { - webDriver.quit(); - } - } catch (WebDriverException | IOException | InterruptedException e) { - LOG.warn("Failed to quit web driver", e); - } finally { - try { - //TODO take out into a separate method - // Wait for processes disappear, this might take a few seconds - if (SystemUtils.IS_OS_WINDOWS) { - String brwsrNm = BROWSER_NAME.toLowerCase().trim(); - if ("ie".equals(brwsrNm)) { - brwsrNm = "iexplore"; - } - int i = 0; - while (i <= 10) { - if (Runtime.getRuntime().exec("tasklist | findstr " + brwsrNm).waitFor() == 0) { - Thread.sleep(1000); - } else { - i = 10; - } - } - } - } catch (IOException | InterruptedException e) { - LOG.warn("Failed to wait for browser processes finish", e); - } - } - - setWebDriver(null); - PageFactoryCore = null; } - /** - * - * @param driver TODO - * @param page TODO - */ public static void initElements(WebDriver driver, Object page) { org.openqa.selenium.support.PageFactory.initElements(driver, page); } - /** - * - * @param decorator TODO - * @param page TODO - */ public static void initElements(FieldDecorator decorator, Object page) { org.openqa.selenium.support.PageFactory.initElements(decorator, page); } @@ -256,10 +82,10 @@ public static void initElements(FieldDecorator decorator, Object page) { * @return PageFactory */ public static PageWrapper getInstance() { - if (null == PageFactoryCore) { - PageFactoryCore = new PageWrapper(PAGES_PACKAGE); + if (null == PageWrapper) { + PageWrapper = new PageWrapper(PAGES_PACKAGE); } - return PageFactoryCore; + return PageWrapper; } /** @@ -274,13 +100,6 @@ public static Actions getActions() { return actions; } - /** - * @param aWebDriver the webDriver to set - */ - public static void setWebDriver(WebDriver aWebDriver) { - webDriver = aWebDriver; - } - /** * @return the browserName */ @@ -309,13 +128,6 @@ public static int getTimeOutInSeconds() { return Integer.parseInt(TIMEOUT) / 1000; } - /** - * @param aProxy the proxy to set - */ - public static void setProxy(BrowserMobProxy aProxy) { - proxy = aProxy; - } - /** * @return the pageRepository */ @@ -341,16 +153,25 @@ public static void setAspectsDisabled(boolean aAspectsDisabled) { aspectsDisabled = aAspectsDisabled; } - /** - * @return the videoRecorder - */ -// public static VideoRecorder getVideoRecorder() { -// return videoRecorder; -// } - /** - * - */ public static void setVideoRecorderToNull() { videoRecorder = null; } + + public static Environment getEnvironment() { + switch (ENVIRONMENT) { + case ENVIRONMENT_WEB: + return Environment.WEB; + case ENVIRONMENT_MOBILE: + return Environment.MOBILE; + default: + throw new FactoryRuntimeException("Environment '" + ENVIRONMENT + "' is not supported"); + } + } + + /** + * @return the INITIAL_URL + */ + public static String getInitialUrl() { + return INITIAL_URL; + } } diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/aspects/ClickAspect.java b/src/main/java/ru/sbtqa/tag/pagefactory/aspects/ClickAspect.java index aca5956..5955fc0 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/aspects/ClickAspect.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/aspects/ClickAspect.java @@ -10,70 +10,57 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import ru.sbtqa.tag.datajack.Stash; -import ru.sbtqa.tag.pagefactory.DriverExtensions; import ru.sbtqa.tag.pagefactory.Page; import ru.sbtqa.tag.pagefactory.PageFactory; +import ru.sbtqa.tag.pagefactory.extensions.WebExtension; +import ru.sbtqa.tag.pagefactory.support.Environment; import ru.sbtqa.tag.qautils.properties.Props; import ru.yandex.qatools.htmlelements.element.TypifiedElement; @Aspect public class ClickAspect { - /** - *

- * clickMethod.

- */ @Pointcut("call(* org.openqa.selenium.WebElement.click()) || call(* ru.yandex.qatools.htmlelements.element.*.click()) ") public void clickMethod() { } - /** - *

- * doAroundClick.

- * - * @param joinPoint a {@link org.aspectj.lang.ProceedingJoinPoint} object. - * @throws java.lang.Throwable if any. - */ @Around("clickMethod()") public void doAroundClick(ProceedingJoinPoint joinPoint) throws Throwable { - String elementHighlightStyle = null; WebElement targetWebElement; - Class elementRedirect; + Class elementRedirect; if (joinPoint.getTarget() instanceof TypifiedElement) { targetWebElement = ((TypifiedElement) joinPoint.getTarget()).getWrappedElement(); - TypifiedElement typifiedElement = (TypifiedElement) joinPoint.getTarget(); elementRedirect = PageFactory.getInstance().getCurrentPage().getElementRedirect(typifiedElement); - } else if (joinPoint.getTarget() instanceof WebElement) { targetWebElement = (WebElement) joinPoint.getTarget(); - elementRedirect = PageFactory.getInstance().getCurrentPage().getElementRedirect(targetWebElement); - } else { return; } - if (Boolean.valueOf(Props.get("video.highlight.enable"))) { - elementHighlightStyle = DriverExtensions.highlightElementOn(targetWebElement); + String elementHighlightStyle = null; + boolean isVideoHighlightEnable = Boolean.valueOf(Props.get("video.highlight.enable")); + if (isVideoHighlightEnable) { + elementHighlightStyle = WebExtension.highlightElementOn(targetWebElement); } - Stash.put("beforeClickHandles", PageFactory.getWebDriver().getWindowHandles()); + if (PageFactory.getEnvironment() == Environment.WEB) { + Stash.put("beforeClickHandles", PageFactory.getWebDriver().getWindowHandles()); + } -// boolean isReinitNeeded = ExperianModel.getElementRePageFactory(targetWebElement, PageFactory.getInstance().currentPage); if (!PageFactory.isAspectsDisabled()) { Actions actions = new Actions(PageFactory.getWebDriver()); - //TODO: для андроеда тут все выполнялось в цикле. Надо если что поставить иф if ("IE".equals(PageFactory.getBrowserName())) { Dimension size = PageFactory.getWebDriver().manage().window().getSize(); Point elementLocation = (targetWebElement).getLocation(); Dimension elementSize = (targetWebElement).getSize(); - //Если элемент находится за пределами видимой области, включаем скролл + //scroll to invisible element if (size.getHeight() < (elementLocation.getY() + elementSize.getHeight() + 200)) { ((JavascriptExecutor) PageFactory.getWebDriver()). - executeScript("window.scroll(" + elementLocation.getX() + "," - + (elementLocation.getY() - 200) + ");"); + executeScript("window.scroll(" + elementLocation.getX() + "," + + (elementLocation.getY() - 200) + ");"); } } @@ -94,13 +81,9 @@ public void doAroundClick(ProceedingJoinPoint joinPoint) throws Throwable { if (null != elementRedirect) { PageFactory.getInstance().getPage(elementRedirect); } -// if (isReinitNeeded) { -// PageFactory.getDriverExtensions().waitForPageToLoad(); -// ExperianModel.initElements(PageFactory.getWebDriver(), PageFactory.getInstance().currentPage); -// } - if (Boolean.valueOf(Props.get("video.highlight.enable"))) { - DriverExtensions.highlightElementOff(targetWebElement, elementHighlightStyle); + if (isVideoHighlightEnable) { + WebExtension.highlightElementOff(targetWebElement, elementHighlightStyle); } } diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/drivers/TagMobileDriver.java b/src/main/java/ru/sbtqa/tag/pagefactory/drivers/TagMobileDriver.java new file mode 100644 index 0000000..ce847b9 --- /dev/null +++ b/src/main/java/ru/sbtqa/tag/pagefactory/drivers/TagMobileDriver.java @@ -0,0 +1,69 @@ +package ru.sbtqa.tag.pagefactory.drivers; + +import io.appium.java_client.AppiumDriver; +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.android.AndroidElement; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.sbtqa.tag.pagefactory.PageFactory; +import static ru.sbtqa.tag.pagefactory.PageFactory.setAspectsDisabled; +import ru.sbtqa.tag.pagefactory.exceptions.FactoryRuntimeException; +import ru.sbtqa.tag.pagefactory.support.Environment; +import ru.sbtqa.tag.qautils.properties.Props; +import ru.sbtqa.tag.videorecorder.VideoRecorder; + +public class TagMobileDriver { + + private static final Logger LOG = LoggerFactory.getLogger(TagMobileDriver.class); + + private static AppiumDriver mobileDriver; + + public static AppiumDriver getDriver() { + if (Environment.MOBILE != PageFactory.getEnvironment()) { + throw new FactoryRuntimeException("Failed to get mobile driver while environment is not mobile"); + } + + if (null == mobileDriver) { + if (Boolean.valueOf(Props.get("video.enable"))) { + VideoRecorder.getInstance().startRecording(); + } + + createDriver(); + } + return mobileDriver; + } + + private static void createDriver() { + DesiredCapabilities capabilities = new DesiredCapabilities(); + capabilities.setCapability("deviceName", Props.get("appium.device.name")); + capabilities.setCapability("platformVersion", Props.get("appium.device.platform")); + capabilities.setCapability("appPackage", Props.get("appium.app.package")); + capabilities.setCapability("appActivity", Props.get("appium.app.activity")); + capabilities.setCapability("autoGrantPermissions", "true"); + capabilities.setCapability("unicodeKeyboard", "true"); + capabilities.setCapability("resetKeyboard", "true"); + LOG.info("Capabilities are {}", capabilities); + + URL url; + try { + url = new URL(PageFactory.getInitialUrl()); + } catch (MalformedURLException e) { + throw new FactoryRuntimeException("Failed to connect to appium on url " + PageFactory.getInitialUrl(), e); + } + + setAspectsDisabled(true); + LOG.debug("Aspect disabled"); + mobileDriver = new AndroidDriver<>(url, capabilities); + LOG.info("Mobile driver created {}", mobileDriver); + } + + public static void dispose() { + if (mobileDriver != null) { + mobileDriver.quit(); + } + } +} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/drivers/TagWebDriver.java b/src/main/java/ru/sbtqa/tag/pagefactory/drivers/TagWebDriver.java new file mode 100644 index 0000000..f3ae65a --- /dev/null +++ b/src/main/java/ru/sbtqa/tag/pagefactory/drivers/TagWebDriver.java @@ -0,0 +1,229 @@ +package ru.sbtqa.tag.pagefactory.drivers; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import net.lightbody.bmp.BrowserMobProxy; +import net.lightbody.bmp.BrowserMobProxyServer; +import net.lightbody.bmp.client.ClientUtil; +import org.apache.commons.lang3.SystemUtils; +import org.openqa.selenium.Alert; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Proxy; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.ie.InternetExplorerDriver; +import org.openqa.selenium.remote.CapabilityType; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.remote.UnreachableBrowserException; +import org.openqa.selenium.safari.SafariDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.sbtqa.tag.pagefactory.PageFactory; +import static ru.sbtqa.tag.pagefactory.PageFactory.getTimeOutInSeconds; +import ru.sbtqa.tag.pagefactory.exceptions.FactoryRuntimeException; +import ru.sbtqa.tag.pagefactory.exceptions.UnsupportedBrowserException; +import ru.sbtqa.tag.pagefactory.support.DesiredCapabilitiesParser; +import ru.sbtqa.tag.pagefactory.support.Environment; +import ru.sbtqa.tag.qautils.properties.Props; +import ru.sbtqa.tag.videorecorder.VideoRecorder; + +public class TagWebDriver { + + private static final Logger log = LoggerFactory.getLogger(TagWebDriver.class); + + private static WebDriver webDriver; + private static final int ATTEMPTS_TO_START_WEBDRIVER = Integer.parseInt(Props.get("driver.create.attempts", "3")); + private static BrowserMobProxy proxy; + private static final String WEBDRIVER_PATH = "src/test/resources/webdrivers/"; + + public static org.openqa.selenium.WebDriver getDriver() { + if (Environment.WEB != PageFactory.getEnvironment()) { + throw new FactoryRuntimeException("Failed to get web driver while environment is not web"); + } + + if (null == webDriver) { + if (Boolean.valueOf(Props.get("video.enable"))) { + VideoRecorder.getInstance().startRecording(); + } + + for (int i = 1; i <= ATTEMPTS_TO_START_WEBDRIVER; i++) { + log.info("Attempt #" + i + " to start web driver"); + try { + createDriver(); + break; + } catch (UnreachableBrowserException e) { + log.warn("Failed to create web driver. Attempt number {}", i, e); + if (null != webDriver) { + // Don't dispose when driver is already null, cuz it causes new driver creation at Init.getWebDriver() + dispose(); + } + } catch (UnsupportedBrowserException e) { + log.error("Failed to create web driver", e); + break; + } + } + } + return webDriver; + } + + private static void createDriver() throws UnsupportedBrowserException { + DesiredCapabilities capabilities = new DesiredCapabilitiesParser().parse(); + + if (Props.get("webdriver.remote.host").isEmpty()) { + + //Local proxy available on local webdriver instances only + if (!Props.get("proxy.enable").isEmpty()) { + setProxy(new BrowserMobProxyServer()); + proxy.start(0); + Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); + capabilities.setCapability(CapabilityType.PROXY, seleniumProxy); + } + switch (PageFactory.getBrowserName()) { + case "Firefox": + capabilities.setBrowserName("firefox"); + setWebDriver(new FirefoxDriver(capabilities)); + break; + case "Safari": + capabilities.setBrowserName("safari"); + setWebDriver(new SafariDriver(capabilities)); + break; + case "Chrome": + File chromeDriver = new File(WEBDRIVER_PATH + "chromedriver.exe"); + System.setProperty("webdriver.chrome.driver", chromeDriver.getAbsolutePath()); + capabilities.setBrowserName("chrome"); + setWebDriver(new ChromeDriver(capabilities)); + break; + case "Opera": + throw new UnsupportedOperationException("Opera browser is not supported yet."); + case "IE": + File IEdriver = new File(WEBDRIVER_PATH + "IEDriverServer.exe"); + System.setProperty("webdriver.ie.driver", IEdriver.getAbsolutePath()); + capabilities.setBrowserName("internet explorer"); + setWebDriver(new InternetExplorerDriver(capabilities)); + break; + default: + throw new UnsupportedBrowserException("'" + PageFactory.getBrowserName() + "' is not supported yet"); + } + } else { + + switch (PageFactory.getBrowserName()) { + case "Firefox": + capabilities.setBrowserName("firefox"); + break; + case "Safari": + capabilities.setBrowserName("safari"); + break; + case "Chrome": + File chromeDriver = new File(WEBDRIVER_PATH + "chromedriver.exe"); + System.setProperty("webdriver.chrome.driver", chromeDriver.getAbsolutePath()); + capabilities.setBrowserName("chrome"); + break; + case "Opera": + throw new UnsupportedOperationException("Opera browser supported as Chrome So change config to chrome."); + case "IE": + File IEdriver = new File(WEBDRIVER_PATH + "IEDriverServer.exe"); + System.setProperty("webdriver.ie.driver", IEdriver.getAbsolutePath()); + capabilities.setBrowserName("internet explorer"); + break; + default: + throw new UnsupportedBrowserException("'" + PageFactory.getBrowserName() + "' is not supported yet"); + } + try { + URL remoreUrl = new URL("http://" + Props.get("webdriver.remote.host") + ":4444/wd/hub"); + setWebDriver(new RemoteWebDriver(remoreUrl, capabilities)); + } catch (MalformedURLException e) { + log.error("Can not parse remote url. Check webdriver.remote.host property"); + } + } + webDriver.manage().timeouts().pageLoadTimeout(getTimeOutInSeconds(), TimeUnit.SECONDS); + webDriver.manage().window().maximize(); + webDriver.get(PageFactory.getInitialUrl()); + } + + public static void dispose() { + try { + log.info("Checking any alert opened"); + WebDriverWait alertAwaiter = new WebDriverWait(webDriver, 2); + alertAwaiter.until(ExpectedConditions.alertIsPresent()); + Alert alert = webDriver.switchTo().alert(); + log.info("Got an alert: " + alert.getText() + "\n Closing it."); + alert.dismiss(); + } catch (WebDriverException e) { + log.debug("No alert opened. Closing webdriver.", e); + } + + Set windowHandlesSet = webDriver.getWindowHandles(); + try { + if (windowHandlesSet.size() > 1) { + for (String winHandle : windowHandlesSet) { + webDriver.switchTo().window(winHandle); + ((JavascriptExecutor) webDriver).executeScript( + "var objWin = window.self;" + + "objWin.open('','_self','');" + + "objWin.close();"); + } + } + } catch (Exception e) { + log.warn("Failed to kill all of the iexplore windows", e); + } + + try { + if ("IE".equals(PageFactory.getBrowserName()) + && Boolean.parseBoolean(Props.get("browser.ie.killOnDispose", "true"))) { + // Kill IE by Windows means instead of webdriver.quit() + Runtime.getRuntime().exec("taskkill /f /im iexplore.exe").waitFor(); + Runtime.getRuntime().exec("taskkill /f /im IEDriverServer.exe").waitFor(); + } else { + webDriver.quit(); + } + } catch (WebDriverException | IOException | InterruptedException e) { + log.warn("Failed to quit web driver", e); + } finally { + try { + //TODO take out into a separate method + // Wait for processes disappear, this might take a few seconds + if (SystemUtils.IS_OS_WINDOWS) { + String brwsrNm = PageFactory.getBrowserName().toLowerCase().trim(); + if ("ie".equals(brwsrNm)) { + brwsrNm = "iexplore"; + } + int i = 0; + while (i <= 10) { + if (Runtime.getRuntime().exec("tasklist | findstr " + brwsrNm).waitFor() == 0) { + Thread.sleep(1000); + } else { + i = 10; + } + } + } + } catch (IOException | InterruptedException e) { + log.warn("Failed to wait for browser processes finish", e); + } + } + + setWebDriver(null); + } + + /** + * @param aWebDriver the webDriver to set + */ + public static void setWebDriver(WebDriver aWebDriver) { + webDriver = aWebDriver; + } + + /** + * @param aProxy the proxy to set + */ + public static void setProxy(BrowserMobProxy aProxy) { + proxy = aProxy; + } +} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/exceptions/GetValueException.java b/src/main/java/ru/sbtqa/tag/pagefactory/exceptions/SwipeException.java similarity index 66% rename from src/main/java/ru/sbtqa/tag/pagefactory/exceptions/GetValueException.java rename to src/main/java/ru/sbtqa/tag/pagefactory/exceptions/SwipeException.java index b595fbc..e612725 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/exceptions/GetValueException.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/exceptions/SwipeException.java @@ -1,12 +1,12 @@ package ru.sbtqa.tag.pagefactory.exceptions; -public class GetValueException extends Exception { +public class SwipeException extends PageException { /** - * + * * @param e a {@link java.lang.Throwable} object. */ - public GetValueException(Throwable e) { + public SwipeException(Throwable e) { super(e); } @@ -15,7 +15,7 @@ public GetValueException(Throwable e) { * @param message a {@link java.lang.String} object. * @param e a {@link java.lang.Throwable} object. */ - public GetValueException(String message, Throwable e) { + public SwipeException(String message, Throwable e) { super(message, e); } @@ -23,7 +23,7 @@ public GetValueException(String message, Throwable e) { * * @param message a {@link java.lang.String} object. */ - public GetValueException(String message) { + public SwipeException(String message) { super(message); } diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/extensions/DriverExtension.java b/src/main/java/ru/sbtqa/tag/pagefactory/extensions/DriverExtension.java new file mode 100644 index 0000000..be2be38 --- /dev/null +++ b/src/main/java/ru/sbtqa/tag/pagefactory/extensions/DriverExtension.java @@ -0,0 +1,244 @@ +package ru.sbtqa.tag.pagefactory.extensions; + +import org.junit.Assert; +import org.openqa.selenium.Alert; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.TimeoutException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.sbtqa.tag.pagefactory.PageFactory; +import ru.sbtqa.tag.pagefactory.exceptions.WaitException; +import ru.sbtqa.tag.qautils.managers.DateManager; + +public class DriverExtension { + + private static final Logger LOG = LoggerFactory.getLogger(DriverExtension.class); + + /** + * Wait until element present + * + * @param webElement Desired web element + */ + public static void waitUntilElementPresent(WebElement webElement) { + new WebDriverWait(PageFactory.getDriver(), PageFactory.getTimeOutInSeconds()). + until(ExpectedConditions.visibilityOf(webElement)); + } + + /** + * Wait until element present + * + * @param webElement Desired web element + * @param timeout Timeout in seconds + */ + public static void waitUntilElementPresent(WebElement webElement, int timeout) { + new WebDriverWait(PageFactory.getDriver(), timeout). + until(ExpectedConditions.visibilityOf(webElement)); + } + + /** + * Wait until element present + * + * @param webElement Desired web element + */ + public static void waitUntilElementToBeClickable(WebElement webElement) { + new WebDriverWait(PageFactory.getDriver(), PageFactory.getTimeOutInSeconds()). + until(ExpectedConditions.elementToBeClickable(webElement)); + } + + /** + * Wait until element present + * + * @param webElement Desired web element + * @param timeout Timeout in seconds + */ + public static void waitUntilElementToBeClickable(WebElement webElement, int timeout) { + new WebDriverWait(PageFactory.getDriver(), timeout). + until(ExpectedConditions.elementToBeClickable(webElement)); + } + + /** + * Wait until element is present and enable to check page prepare to work + * + * @param webElement Desired web element + */ + public static void waitUntilPagePrepared(WebElement webElement) { + try { + new WebDriverWait(PageFactory.getDriver(), PageFactory.getTimeOutInSeconds() / 2). + until(ExpectedConditions.visibilityOf(webElement)); + } catch (Exception | AssertionError e) { + LOG.debug("Element {} does not become visible after timeout", webElement, e); + PageFactory.getDriver().navigate().refresh(); + LOG.debug("Page refreshed"); + new WebDriverWait(PageFactory.getDriver(), PageFactory.getTimeOutInSeconds()). + until(ExpectedConditions.visibilityOf(webElement)); + } + } + + /** + * Wait until element present + * + * @param by a {@link org.openqa.selenium.By} object. + * @return return appeared WebElement + */ + public static WebElement waitUntilElementAppearsInDom(By by) { + new WebDriverWait(PageFactory.getDriver(), PageFactory.getTimeOutInSeconds()) + .until(ExpectedConditions.presenceOfElementLocated(by)); + + return PageFactory.getDriver().findElement(by); + } + + /** + * Wait until element present + * + * @param by a {@link org.openqa.selenium.By} object. + * @param timeout timeout in seconds + * @return return appeared WebElement + */ + public static WebElement waitUntilElementAppearsInDom(By by, long timeout) { + new WebDriverWait(PageFactory.getDriver(), timeout) + .until(ExpectedConditions.presenceOfElementLocated(by)); + + return PageFactory.getDriver().findElement(by); + } + + /** + * Wait until element gone from dom + * + * @param timeout in milliseconds + * @param webElement a {@link org.openqa.selenium.WebElement} object. + */ + public static void waitUntilElementGoneFromDom(WebElement webElement, long timeout) { + Long start = DateManager.getCurrentTimestamp(); + while (DateManager.getCurrentTimestamp() < start + timeout) { + try { + if (!webElement.isDisplayed()) { + return; + } + } catch (NoSuchElementException | StaleElementReferenceException e) { + LOG.debug("There is no element {} in dom", webElement, e); + return; + } + sleep(1); + } + throw new NoSuchElementException("Timed out after " + timeout + " milliseconds waiting for web element '" + webElement.toString() + "' gone from DOM"); + } + + /** + * + * @param element a {@link org.openqa.selenium.WebElement} object. + */ + public static void waitUntilElementGetInvisible(WebElement element) { + new WebDriverWait(PageFactory.getDriver(), PageFactory.getTimeOutInSeconds()) + .until(ExpectedConditions.not(ExpectedConditions.visibilityOf(element))); + } + + /** + *

+ * waitForElementGetEnabled.

+ * + * @param webElement a {@link org.openqa.selenium.WebElement} object. + * @param timeout a long. + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO + */ + public static void waitForElementGetEnabled(WebElement webElement, long timeout) throws WaitException { + long timeoutTime = DateManager.getCurrentTimestamp() + timeout; + while (timeoutTime > DateManager.getCurrentTimestamp()) { + sleep(1); + try { + if (webElement.isEnabled()) { + return; + } + } catch (Exception e) { + LOG.debug("Target element still not enable", e); + } + + } + throw new WaitException("Timed out after '" + timeout + "' milliseconds waiting for availability of '" + webElement + "'"); + } + + /** + * Accept any alert regardless of its message + * + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException if alert didn't appear during timeout + */ + public static void acceptAlert() throws WaitException { + interactWithAlert("", true); + } + + /** + * Dismiss any alert regardless of its message + * + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException if alert didn't appear during timeout + */ + public static void dismissAlert() throws WaitException { + interactWithAlert("", false); + } + + /** + * Wait for an alert with corresponding text (if specified). Depending on the decision, either accept it or decline + * If messageText is empty, text doesn't matter + * + * @param messageText text of an alert. If empty string is provided, it is being ignored + * @param decision true - accept, false - dismiss + * @throws WaitException in case if alert didn't appear during default wait timeout + */ + public static void interactWithAlert(String messageText, boolean decision) throws WaitException { + long timeoutTime = System.currentTimeMillis() + PageFactory.getTimeOut(); + + while (timeoutTime > System.currentTimeMillis()) { + try { + Alert alert = PageFactory.getDriver().switchTo().alert(); + if (!messageText.isEmpty()) { + Assert.assertEquals(alert.getText(), messageText); + } + if (decision) { + alert.accept(); + } else { + alert.dismiss(); + } + return; + } catch (Exception e) { + LOG.debug("Alert has not appeared yet", e); + } + sleep(1); + } + throw new WaitException("Timed out after '" + PageFactory.getTimeOutInSeconds() + "' seconds waiting for alert to accept"); + } + + + + /** + * + * @param text a {@link java.lang.String} object. + * @param timeout a {int} object. wait text during sec period + * @return true if exists + */ + public static boolean checkElementWithTextIsPresent(String text, int timeout) { + try { + new WebDriverWait(PageFactory.getDriver(), timeout) + .until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), '" + text + "')]"))); + return true; + } catch (TimeoutException e) { + LOG.debug("Element with text {} is not located on page", text, e); + return false; + } + } + + /** + * + * @param sec a int. + */ + private static void sleep(int sec) { + try { + Thread.sleep(sec * 1000L); + } catch (InterruptedException e) { + LOG.warn("Error while thread is sleeping", e); + Thread.currentThread().interrupt(); + } + } +} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/extensions/MobileExtension.java b/src/main/java/ru/sbtqa/tag/pagefactory/extensions/MobileExtension.java new file mode 100644 index 0000000..397230c --- /dev/null +++ b/src/main/java/ru/sbtqa/tag/pagefactory/extensions/MobileExtension.java @@ -0,0 +1,173 @@ +package ru.sbtqa.tag.pagefactory.extensions; + +import java.util.List; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.sbtqa.tag.pagefactory.PageFactory; +import ru.sbtqa.tag.pagefactory.exceptions.SwipeException; +import ru.sbtqa.tag.qautils.strategies.DirectionStrategy; +import ru.sbtqa.tag.qautils.strategies.MatchStrategy; + +public class MobileExtension { + + private static final Logger LOG = LoggerFactory.getLogger(MobileExtension.class); + + private static final int DEFAULT_SWIPE_TIME = 3000; + private static final int DEFAULT_SWIPE_DEPTH = 256; + private static final double INDENT_BOTTOM = 0.80; + private static final double INDENT_TOP = 0.20; + private static final double INDENT_LEFT = 0.30; + private static final double INDENT_RIGHT = 0.70; + + /** + * Swipe element to direction + * + * @param element element to swipe + * @param direction swipe direction + * @throws SwipeException if there is an error while swiping + */ + public static void swipe(WebElement element, DirectionStrategy direction) throws SwipeException { + swipe(element, direction, DEFAULT_SWIPE_TIME); + } + + /** + * Swipe element to direction + * + * @param element taget element to swipe + * @param direction swipe direction + * @param time how fast element should be swiped + * @throws SwipeException if there is an error while swiping + */ + public static void swipe(WebElement element, DirectionStrategy direction, int time) throws SwipeException { + Dimension size = element.getSize(); + Point location = element.getLocation(); + swipe(location, size, direction, time); + } + + /** + * Swipe screen to direction + * + * @param direction swipe direction + * @throws SwipeException if there is an error while swiping + */ + public static void swipe(DirectionStrategy direction) throws SwipeException { + swipe(direction, DEFAULT_SWIPE_TIME); + } + + /** + * Swipe screen to direction + * + * @param direction swipe direction + * @param time how fast screen should be swiped + * @throws SwipeException if there is an error while swiping + */ + public static void swipe(DirectionStrategy direction, int time) throws SwipeException { + Dimension size = PageFactory.getMobileDriver().manage().window().getSize(); + swipe(new Point(0, 0), size, direction, time); + } + + /** + * Swipe to direction + * + * @param location top left-hand corner of the element + * @param size width and height of the element + * @param direction swipe direction + * @param time how fast screen should be swiped + * @throws SwipeException if there is an error while swiping + */ + private static void swipe(Point location, Dimension size, DirectionStrategy direction, int time) throws SwipeException { + int startx, endx, starty, endy; + switch (direction) { + case DOWN: + startx = endx = size.width / 2; + starty = (int) (size.height * INDENT_BOTTOM); + endy = (int) (size.height * INDENT_TOP); + break; + case UP: + startx = endx = size.width / 2; + starty = (int) (size.height * INDENT_TOP); + endy = (int) (size.height * INDENT_BOTTOM); + break; + case RIGHT: + startx = (int) (size.width * INDENT_RIGHT); + endx = (int) (size.width * INDENT_LEFT); + starty = endy = size.height / 2; + break; + case LEFT: + startx = (int) (size.width * INDENT_LEFT); + endx = (int) (size.width * INDENT_RIGHT); + starty = endy = size.height / 2; + break; + default: + throw new SwipeException("Failed to swipe to direction " + direction); + } + + int x = location.getX(); + int y = location.getY(); + LOG.debug("Swipe parameters: location {}, dimension {}, direction {}, time {}", location, size, direction, time); + PageFactory.getMobileDriver().swipe(x + startx, y + starty, x + endx, y + endy, time); + } + + /** + * Swipe until the text becomes visible + * + * @param direction swipe direction + * @param text text on page to swipe to + * @throws SwipeException if there is an error while swiping + */ + public static void swipeToText(DirectionStrategy direction, String text) throws SwipeException { + swipeToText(direction, text, MatchStrategy.EXACT); + } + + /** + * Swipe until the text becomes visible + * + * @param direction swipe direction + * @param text text on page to swipe to + * @param strategy contains or exact + * @throws SwipeException if there is an error while swiping + */ + public static void swipeToText(DirectionStrategy direction, String text, MatchStrategy strategy) throws SwipeException { + swipeToText(direction, text, MatchStrategy.EXACT, DEFAULT_SWIPE_DEPTH); + } + + /** + * Swipe until the text becomes visible + * + * @param direction swipe direction + * @param text text on page to swipe to + * @param strategy contains or exact + * @param depth the amount of swipe action + * @throws SwipeException if there is an error while swiping + */ + public static void swipeToText(DirectionStrategy direction, String text, MatchStrategy strategy, int depth) throws SwipeException { + for (int depthCounter = 0; depthCounter < depth; depthCounter++) { + String oldPageSource = PageFactory.getDriver().getPageSource(); + switch (strategy) { + case EXACT: + if (PageFactory.getMobileDriver().findElementsByXPath("//*[@text='" + text + "']").size() > 0) { + return; + } + case CONTAINS: + List textViews = PageFactory.getMobileDriver().findElementsByClassName("android.widget.TextView"); + if (textViews.size() > 0) { + for (WebElement textView : textViews) { + if (textView.getText().contains(text)) { + return; + } + } + } + } + swipe(direction); + + if (PageFactory.getDriver().getPageSource().equals(oldPageSource)) { + throw new SwipeException("Swiping limit is reached. Text not found"); + } + } + + throw new SwipeException("Swiping depth is reached. Text not found"); + } +} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/extensions/WebExtension.java b/src/main/java/ru/sbtqa/tag/pagefactory/extensions/WebExtension.java new file mode 100644 index 0000000..f40cb57 --- /dev/null +++ b/src/main/java/ru/sbtqa/tag/pagefactory/extensions/WebExtension.java @@ -0,0 +1,193 @@ +package ru.sbtqa.tag.pagefactory.extensions; + +import java.util.Set; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.sbtqa.tag.pagefactory.PageFactory; +import ru.sbtqa.tag.pagefactory.exceptions.WaitException; +import static ru.sbtqa.tag.pagefactory.extensions.DriverExtension.waitUntilElementAppearsInDom; +import ru.sbtqa.tag.qautils.managers.DateManager; + +public class WebExtension { + + private static final Logger LOG = LoggerFactory.getLogger(WebExtension.class); + + /** + * Get outer element text. Used for get text from checkboxes and radio + * buttons + * + * @param webElement TODO + * @return text of element + */ + public static String getElementValue(WebElement webElement) throws IllegalArgumentException { + String elementValue = "Cannot parse element"; + String elementId = webElement.getAttribute("id"); + + if (elementId == null) { + throw new IllegalArgumentException("Getting value is not support in element without id"); + } + + WebElement possibleTextMatcher = PageFactory.getWebDriver().findElement(By.xpath("//*[@id='" + elementId + "']/..")); + if (possibleTextMatcher.getText().isEmpty()) { + possibleTextMatcher = PageFactory.getWebDriver().findElement(By.xpath("//*[@id='" + elementId + "']/../..")); + if ("tr".equals(possibleTextMatcher.getTagName())) { + elementValue = possibleTextMatcher.getText(); + } + } else { + elementValue = possibleTextMatcher.getText(); + } + return elementValue; + } + + /** + * Wait for page prepared with javascript + * + * @param stopRecursion TODO + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO + */ + public static void waitForPageToLoad(boolean... stopRecursion) throws WaitException { + long timeoutTime = System.currentTimeMillis() + PageFactory.getTimeOut(); + while (timeoutTime > System.currentTimeMillis()) { + try { + if ("complete".equals((String) ((JavascriptExecutor) PageFactory.getWebDriver()).executeScript("return document.readyState"))) { + return; + } + sleep(1); + } catch (Exception | AssertionError e) { + LOG.debug("Page does not become to ready state", e); + PageFactory.getWebDriver().navigate().refresh(); + LOG.debug("Page refreshed"); + if ((stopRecursion.length == 0) || (stopRecursion.length > 0 && !stopRecursion[0])) { + waitForPageToLoad(true); + } + } + } + + throw new WaitException("Timed out after " + PageFactory.getTimeOutInSeconds() + " seconds waiting for preparedness of page"); + } + + /** + * + * @param webElement a {@link org.openqa.selenium.WebElement} object. + * @param timeout in milliseconds + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO + */ + public static void waitForTextInInputExists(WebElement webElement, long timeout) throws WaitException { + long timeoutTime = DateManager.getCurrentTimestamp() + timeout; + while (timeoutTime > DateManager.getCurrentTimestamp()) { + sleep(1); + if (!webElement.getAttribute("value").isEmpty()) { + return; + } + } + throw new WaitException("Timed out after '" + timeout + "' milliseconds waiting for existence of '" + webElement + "'"); + } + + /** + * Wait until specified text either appears, or disappears from page source + * + * @param text text to search in page source + * @param shouldTextBePresent boolean, self explanatory + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO + */ + public static void waitForTextPresenceInPageSource(String text, boolean shouldTextBePresent) throws WaitException { + long timeoutTime = System.currentTimeMillis() + PageFactory.getTimeOut(); + WebElement body = waitUntilElementAppearsInDom(By.tagName("body")); + while (timeoutTime > System.currentTimeMillis()) { + sleep(1); + if (body.getText().replaceAll("\\s+", "").contains(text.replaceAll("\\s+", "")) == shouldTextBePresent) { + return; + } + } + throw new WaitException("Timed out after '" + PageFactory.getTimeOutInSeconds() + "' seconds waiting for presence of '" + text + "' in page source"); + } + + /** + * + * @param existingHandles TODO + * @param timeout TODO + * @return TODO + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO + */ + public static String findNewWindowHandle(Set existingHandles, int timeout) throws WaitException { + long timeoutTime = System.currentTimeMillis() + timeout; + + while (timeoutTime > System.currentTimeMillis()) { + Set currentHandles = PageFactory.getWebDriver().getWindowHandles(); + + if (currentHandles.size() != existingHandles.size() + || (currentHandles.size() == existingHandles.size() && !currentHandles.equals(existingHandles))) { + for (String currentHandle : currentHandles) { + if (!existingHandles.contains(currentHandle)) { + return currentHandle; + } + } + } + sleep(1); + } + + throw new WaitException("Timed out after '" + timeout + "' milliseconds waiting for new modal window"); + } + + /** + * + * @param existingHandles TODO + * @return TODO + * @throws ru.sbtqa.tag.pagefactory.exceptions.WaitException TODO + */ + public static String findNewWindowHandle(Set existingHandles) throws WaitException { + return findNewWindowHandle(existingHandles, PageFactory.getTimeOut()); + } + + /** + * Turn on element highlight + * + * @param webElement TODO + * @return initial element style + */ + public static String highlightElementOn(WebElement webElement) { + try { + JavascriptExecutor js = (JavascriptExecutor) PageFactory.getWebDriver(); + String style = (String) js.executeScript("return arguments[0].style.border", webElement); + js.executeScript("arguments[0].style.border='3px solid red'", webElement); + return style; + } catch (Exception e) { + LOG.warn("Something went wrong with element highlight", e); + return null; + } + } + + /** + * Turn off element highlight + * + * @param webElement TODO + * @param style element style to set + */ + public static void highlightElementOff(WebElement webElement, String style) { + if (style == null) { + return; + } + try { + JavascriptExecutor js = (JavascriptExecutor) PageFactory.getWebDriver(); + js.executeScript("arguments[0].style.border='" + style + "'", webElement); + } catch (Exception e) { + LOG.debug("Something went wrong with element highlight", e); + } + } + + /** + * + * @param sec a int. + */ + private static void sleep(int sec) { + try { + Thread.sleep(sec * 1000L); + } catch (InterruptedException e) { + LOG.warn("Error while thread is sleeping", e); + Thread.currentThread().interrupt(); + } + } +} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs.java b/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs.java index dda0113..cd6816a 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs.java @@ -2,6 +2,8 @@ import cucumber.api.DataTable; import cucumber.api.java.en.And; +import java.util.ArrayList; +import java.util.List; import org.junit.Assert; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NoSuchElementException; @@ -9,10 +11,12 @@ import ru.sbtqa.tag.pagefactory.PageFactory; import ru.sbtqa.tag.pagefactory.exceptions.PageException; import ru.sbtqa.tag.pagefactory.exceptions.PageInitializationException; +import ru.sbtqa.tag.pagefactory.exceptions.SwipeException; +import ru.sbtqa.tag.pagefactory.extensions.MobileExtension; +import ru.sbtqa.tag.pagefactory.support.Environment; import ru.sbtqa.tag.qautils.errors.AutotestError; +import ru.sbtqa.tag.qautils.strategies.DirectionStrategy; -import java.util.ArrayList; -import java.util.List; import ru.yandex.qatools.htmlelements.element.Button; import ru.yandex.qatools.htmlelements.element.CheckBox; import ru.yandex.qatools.htmlelements.element.HtmlElement; @@ -208,7 +212,8 @@ public void findElementInList(String listTitle, String value) throws PageExcepti */ @And("openPage") public void openPage(String title) throws PageInitializationException { - if (!PageFactory.getWebDriver().getWindowHandles().isEmpty()) { + if (PageFactory.getEnvironment() != Environment.MOBILE && + !PageFactory.getWebDriver().getWindowHandles().isEmpty()) { for (String windowHandle : PageFactory.getWebDriver().getWindowHandles()) { PageFactory.getWebDriver().switchTo().window(windowHandle); } @@ -395,4 +400,18 @@ public void goToPageByUrl(String url) throws PageInitializationException { public void reInitPage() { PageFactory.getWebDriver().navigate().refresh(); } + + /** + * Swipe until text is visible + * + * @param direction direction to swipe + * @param text text on page to swipe to + * @throws SwipeException if the text is not found or swipe depth is reached + */ + @And("swipeToText") + public void swipeToText(String direction, String text) throws SwipeException { + MobileExtension.swipeToText(DirectionStrategy.valueOf(direction.toUpperCase()), text); + } + + } diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/SetupDefsBase.java b/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/SetupStepDefs.java similarity index 97% rename from src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/SetupDefsBase.java rename to src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/SetupStepDefs.java index c013269..4959972 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/SetupDefsBase.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/stepdefs/SetupStepDefs.java @@ -24,9 +24,9 @@ import ru.sbtqa.tag.qautils.reflect.FieldUtilsExt; import ru.yandex.qatools.htmlelements.element.HtmlElement; -public class SetupDefsBase { +public class SetupStepDefs { - private static final Logger LOG = LoggerFactory.getLogger(SetupDefsBase.class); + private static final Logger LOG = LoggerFactory.getLogger(SetupStepDefs.class); @Before() public void setUp() { @@ -51,9 +51,10 @@ public void setUp() { LOG.debug("Failed to kill one of task to kill", e); } - Reflections reflections; - PageFactory.getWebDriver(); + PageFactory.getDriver(); PageFactory.getInstance(); + + Reflections reflections; reflections = new Reflections(PageFactory.getPagesPackage()); Collection allClassesString = reflections.getStore().get("SubTypesScanner").values(); diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/support/Environment.java b/src/main/java/ru/sbtqa/tag/pagefactory/support/Environment.java new file mode 100644 index 0000000..1497ffe --- /dev/null +++ b/src/main/java/ru/sbtqa/tag/pagefactory/support/Environment.java @@ -0,0 +1,5 @@ +package ru.sbtqa.tag.pagefactory.support; + +public enum Environment { + WEB, MOBILE +} diff --git a/src/main/java/ru/sbtqa/tag/pagefactory/support/ScreenShooter.java b/src/main/java/ru/sbtqa/tag/pagefactory/support/ScreenShooter.java index 0aabe86..464b026 100644 --- a/src/main/java/ru/sbtqa/tag/pagefactory/support/ScreenShooter.java +++ b/src/main/java/ru/sbtqa/tag/pagefactory/support/ScreenShooter.java @@ -10,24 +10,23 @@ import javax.imageio.ImageIO; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.sbtqa.tag.pagefactory.PageFactory; import ru.yandex.qatools.allure.annotations.Attachment; public class ScreenShooter { - private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ScreenShooter.class); + private static final Logger LOG = LoggerFactory.getLogger(ScreenShooter.class); /** - * Takes screenshot with WebDriver + * Takes screenshot with driver * * @return screenshot in byte array */ @Attachment(type = "image/png", value = "Screenshot") public static byte[] takeWithDriver() { - return ((PageFactory.getWebDriver() == null) - ? "".getBytes() - : ((TakesScreenshot) PageFactory.getWebDriver()).getScreenshotAs(OutputType.BYTES)); + return ((TakesScreenshot) PageFactory.getDriver()).getScreenshotAs(OutputType.BYTES); } /** diff --git a/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/en.properties b/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/en.properties index 3b81fdc..0535b4c 100644 --- a/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/en.properties +++ b/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/en.properties @@ -1,21 +1,22 @@ -userActionInBlockNoParams=^user in block "([^"]*)" \((.*?)\)$ -userActionInBlockTableParam=^user in block "([^"]*)" \((.*?)\) with the parameters of table$ -userActionInBlockOneParam=^user in block "([^"]*)" \((.*?)\) with a parameter "([^"]*)"$ -userActionInBlockTwoParams=^user in block "([^"]*)" \((.*?)\) with the parameters "([^"]*)" "([^"]*)"$ -findElementInBlock=^user in block "([^"]*)" finds (element|textinput|checkbox|radiobutton|table|header|button|link|image) "([^"]*)"$ -findElementInList=^user in list "([^"]*)" finds the value element "([^"]*)"$ -openPage=^(?:user |he |)(?:is on the page|page is being opened|master tab is being opened) "(.*?)"$ -userActionNoParams=^user \((.*?)\)$ -userActionOneParam=^user \((.*?)\) (?:with param |)"([^"]*)"$ -userActionTwoParams=^user \((.*?)\) (?:with the parameters |)"([^"]*)" "([^"]*)"$ -userActionThreeParams=^user \((.*?)\) (?:with the parameters |)"([^"]*)" "([^"]*)" "([^"]*)"$ -userActionTableParam=^user \((.*?)\) data$ -userDoActionWithObject=^user \((.*?)\) [^"]*"([^"]*) data$ -userActionListParam=^user \((.*?)\) from the list$ +userActionInBlockNoParams=^user in block \"([^\"]*)\" \\((.*?)\\)$ +userActionInBlockTableParam=^user in block \"([^\"]*)\" \\((.*?)\\) with the parameters of table$ +userActionInBlockOneParam=^user in block \"([^\"]*)\" \\((.*?)\\) with a parameter \"([^\"]*)\"$ +userActionInBlockTwoParams=^user in block \"([^\"]*)\" \\((.*?)\\) with the parameters \"([^\"]*)\" \"([^\"]*)\"$ +findElementInBlock=^user in block \"([^\"]*)\" finds (element|textinput|checkbox|radiobutton|table|header|button|link|image) \"([^\"]*)\"$ +findElementInList=^user in list \"([^\"]*)\" finds the value element \"([^\"]*)\"$ +openPage=^(?:user |he |)(?:is on the page|page is being opened|master tab is being opened) \"(.*?)\"$ +userActionNoParams=^user \\((.*?)\\)$ +userActionOneParam=^user \\((.*?)\\) (?:with param |)\"([^\"]*)\"$ +userActionTwoParams=^user \\((.*?)\\) (?:with the parameters |)\"([^\"]*)\" \"([^\"]*)\"$ +userActionThreeParams=^user \\((.*?)\\) (?:with the parameters |)\"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$ +userActionTableParam=^user \\((.*?)\\) data$ +userDoActionWithObject=^user \\((.*?)\\) [^\"]*\"([^\"]*) data$ +userActionListParam=^user \\((.*?)\\) from the list$ openCopyPage=^copy of the page is being opened in a new tab$ switchesToNextTab=^user switches to the next tab$ -urlMatches=^URL matches "(.*?)"$ -closingCurrentWin=^user closes the current window and returns to "(.*?)"$ +urlMatches=^URL matches \"(.*?)\"$ +closingCurrentWin=^user closes the current window and returns to \"(.*?)\"$ backPage=^user push back in the browser$ -goToPageByUrl=^user navigates to page "(.*?)"$ -reInitPage=^user refreshes the page$ \ No newline at end of file +goToPageByUrl=^user navigates to page \"(.*?)\"$ +reInitPage=^user refreshes the page$ +swipeToText=^user swipes "(.*?)" to text "(.*?)"$ \ No newline at end of file diff --git a/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/ru.properties b/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/ru.properties index 78fb195..1eff7a6 100644 --- a/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/ru.properties +++ b/src/main/resources/i18n/ru/sbtqa/tag/pagefactory/stepdefs/GenericStepDefs/ru.properties @@ -1,21 +1,22 @@ -userActionInBlockNoParams=^(?:пользователь |он | )в блоке "([^"]*)" \((.*?)\)$ -userActionInBlockTableParam=^(?:пользователь |он |)в блоке "([^"]*)" \((.*?)\) с параметрами из таблицы$ +userActionInBlockNoParams=^(?:пользователь |он | )в блоке \"([^\"]*)\" \\((.*?)\\)$ +userActionInBlockTableParam=^(?:пользователь |он |)в блоке \"([^\"]*)\" \\((.*?)\\) с параметрами из таблицы$ userActionInBlockOneParam=^(?:пользователь |он |)в блоке \"([^\"]*)\" \\((.*?)\\) с параметром \"([^\"]*)\"$ -userActionInBlockTwoParams=^(?:пользователь |он |)в блоке "([^"]*)" \((.*?)\) с параметрами "([^"]*)" "([^"]*)"$ -findElementInBlock=^(?:пользователь |он |)в блоке "([^"]*)" находит (элемент|текстовое поле|чекбокс|радиобатон|таблицу|заголовок|кнопку|ссылку|изображение) "([^"]*)"$ -findElementInList=^(?:пользователь |он |)в списке "([^"]*)" находит элемент со значением "([^"]*)"$ -openPage=^(?:пользователь |он |)(?:находится на странице|открывается страница|открывается вкладка мастера) "(.*?)"$ -userActionNoParams=^(?:пользователь |он |)\((.*?)\)$ -userActionOneParam=^(?:пользователь |он |)\((.*?)\) (?:с параметром |)"([^"]*)"$ -userActionTwoParams=^(?:пользователь |он |)\((.*?)\) (?:с параметрарми |)"([^"]*)" "([^"]*)"$ -userActionThreeParams=^(?:пользователь |он |)\((.*?)\) (?:с параметрарми |)"([^"]*)" "([^"]*)" "([^"]*)"$ -userActionTableParam=^(?:пользователь |он |)\((.*?)\) данными$ -userDoActionWithObject=^(?:пользователь |он |)\((.*?)\) [^"]*"([^"]*)" данными$ -userActionListParam=^(?:пользователь |он |)\((.*?)\) из списка$ +userActionInBlockTwoParams=^(?:пользователь |он |)в блоке \"([^\"]*)\" \\((.*?)\\) с параметрами \"([^\"]*)\" \"([^\"]*)\"$ +findElementInBlock=^(?:пользователь |он |)в блоке \"([^\"]*)\" находит (элемент|текстовое поле|чекбокс|радиобатон|таблицу|заголовок|кнопку|ссылку|изображение) \"([^\"]*)\"$ +findElementInList=^(?:пользователь |он |)в списке \"([^\"]*)\" находит элемент со значением \"([^\"]*)\"$ +openPage=^(?:пользователь |он |)(?:находится на странице|открывается страница|открывается вкладка мастера) \"(.*?)\"$ +userActionNoParams=^(?:пользователь |он |)\\((.*?)\\)$ +userActionOneParam=^(?:пользователь |он |)\\((.*?)\\) (?:с параметром |)\"([^\"]*)\"$ +userActionTwoParams=^(?:пользователь |он |)\\((.*?)\\) (?:с параметрарми |)\"([^\"]*)\" \"([^\"]*)\"$ +userActionThreeParams=^(?:пользователь |он |)\\((.*?)\\) (?:с параметрарми |)\"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$ +userActionTableParam=^(?:пользователь |он |)\\((.*?)\\) данными$ +userDoActionWithObject=^(?:пользователь |он |)\\((.*?)\\) [^\"]*\"([^\"]*)\" данными$ +userActionListParam=^(?:пользователь |он |)\\((.*?)\\) из списка$ openCopyPage=^открывается копия страницы в новой вкладке$ switchesToNextTab=^(?:пользователь |он |)переключается на соседнюю вкладку$ -urlMatches=^URL соответствует "(.*?)"$ -closingCurrentWin=^(?:пользователь |он |)закрывает текущее окно и возвращается на "(.*?)"$ +urlMatches=^URL соответствует \"(.*?)\"$ +closingCurrentWin=^(?:пользователь |он |)закрывает текущее окно и возвращается на \"(.*?)\"$ backPage=^(?:пользователь |он |)нажимает назад в браузере$ -goToPageByUrl=^(?:пользователь |он |)переходит на страницу "(.*?)" по ссылке$ -reInitPage=^обновляем страницу$ \ No newline at end of file +goToPageByUrl=^(?:пользователь |он |)переходит на страницу \"(.*?)\" по ссылке$ +reInitPage=^обновляем страницу$ +swipeToText=^пользователь свайпает экран \"([^\"]*)\" до текста \"([^\"]*)\"$ \ No newline at end of file