From 767a188c368f6f14d03a683e014835bb9d244152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alaksiej=20Miale=C5=A1ka?= Date: Mon, 6 Jul 2020 17:03:14 +0200 Subject: [PATCH] Feature/support logging of element property getters (#103) * Add DEBUG logging of capabilities, start arguments and options Disable logging of setScriptTimeout if the value wasn't changed Support logging of ElementStateProvider methods * Reworked BrowserFactory, enhance retrying/logging of driver start Add logging of current URL * Renamed local variables in DriverSettings to fix sonar code smell * Add logging of Browser's waitForPageToLoad() * Add logging of Browser's handle alert methods * Enhanced logging for CheckBox and RadioButton elements * Added logging of element property getters Enhanced logging for ComboBox methods * Add logging of JsActions getters: isElementOnScreen and getXPath Removed redundant localization values unused in the current lib * Add retry for driver creation in case of timeout exception * Updated access modificator of getDriver to protected in LocalBrowserFactory Refactored DriverSettings getMapOrEmpty * Add retry to custom BrowserFactory in tests * Corrected values in localization and settings files * Deprecated Form's isDisplayed() method, add state() instead --- pom.xml | 4 +- .../selenium/browser/AqualityServices.java | 5 +- .../aquality/selenium/browser/Browser.java | 11 +++- .../selenium/browser/BrowserFactory.java | 58 ++++++++-------- .../selenium/browser/LocalBrowserFactory.java | 24 +++++-- .../browser/RemoteBrowserFactory.java | 42 +++++++----- .../driversettings/ChromeSettings.java | 1 - .../driversettings/DriverSettings.java | 66 ++++++++++++++----- .../driversettings/FirefoxSettings.java | 1 - .../driversettings/IExplorerSettings.java | 1 + .../aquality/selenium/elements/CheckBox.java | 14 +--- .../selenium/elements/CheckableElement.java | 28 ++++++++ .../aquality/selenium/elements/ComboBox.java | 29 +++++--- .../aquality/selenium/elements/Element.java | 18 +++-- .../elements/ElementStateProvider.java | 60 ++--------------- .../java/aquality/selenium/elements/Link.java | 2 +- .../selenium/elements/RadioButton.java | 7 +- .../aquality/selenium/elements/TextBox.java | 2 +- .../elements/actions/CheckBoxJsActions.java | 22 ++++--- .../elements/actions/ComboBoxJsActions.java | 10 ++- .../selenium/elements/actions/JsActions.java | 8 ++- .../java/aquality/selenium/forms/Form.java | 15 ++++- src/main/resources/localization/be.json | 45 +++++++------ src/main/resources/localization/en.json | 45 +++++++------ src/main/resources/localization/ru.json | 57 ++++++++-------- src/main/resources/log4j.properties | 2 +- src/main/resources/settings.json | 3 +- .../LocalizationManagerTests.java | 13 +++- .../utils/ElementActionRetrierTests.java | 2 +- .../tests/integration/ElementStateTests.java | 4 +- .../java/tests/integration/ElementTests.java | 25 +++++++ .../tests/usecases/BrowserFactoryTests.java | 15 ++++- .../java/tests/usecases/ShoppingCartTest.java | 4 +- src/test/resources/settings.incorrect.json | 3 +- src/test/resources/settings.json | 3 +- src/test/resources/settings.local.json | 3 +- 36 files changed, 386 insertions(+), 266 deletions(-) create mode 100644 src/main/java/aquality/selenium/elements/CheckableElement.java diff --git a/pom.xml b/pom.xml index 732aac6..ba12098 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.aquality-automation aquality-selenium - 2.4.0 + 2.5.0 jar Aquality Selenium Library around Selenium WebDriver @@ -73,7 +73,7 @@ com.github.aquality-automation aquality-selenium-core - 1.1.0 + 1.2.0 diff --git a/src/main/java/aquality/selenium/browser/AqualityServices.java b/src/main/java/aquality/selenium/browser/AqualityServices.java index 0c71400..7d9e17d 100644 --- a/src/main/java/aquality/selenium/browser/AqualityServices.java +++ b/src/main/java/aquality/selenium/browser/AqualityServices.java @@ -2,8 +2,10 @@ import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.IConfiguration; +import aquality.selenium.configuration.ITimeoutConfiguration; import aquality.selenium.core.localization.ILocalizedLogger; import aquality.selenium.core.logging.Logger; +import aquality.selenium.core.utilities.IActionRetrier; import aquality.selenium.core.waitings.IConditionalWait; import aquality.selenium.elements.interfaces.IElementFactory; import com.google.inject.Injector; @@ -66,7 +68,8 @@ private static Injector getServiceProvider() { */ public static void setDefaultBrowserFactory() { IBrowserFactory browserFactory = getBrowserProfile().isRemote() - ? new RemoteBrowserFactory() : new LocalBrowserFactory(); + ? new RemoteBrowserFactory(get(IActionRetrier.class), getBrowserProfile(), get(ITimeoutConfiguration.class), getLocalizedLogger()) + : new LocalBrowserFactory(get(IActionRetrier.class), getBrowserProfile(), getLocalizedLogger()); setBrowserFactory(browserFactory); } diff --git a/src/main/java/aquality/selenium/browser/Browser.java b/src/main/java/aquality/selenium/browser/Browser.java index 2f45657..21c5bd7 100644 --- a/src/main/java/aquality/selenium/browser/Browser.java +++ b/src/main/java/aquality/selenium/browser/Browser.java @@ -109,7 +109,9 @@ public void maximize() { */ public String getCurrentUrl() { localizedLogger.info("loc.browser.getUrl"); - return getDriver().getCurrentUrl(); + String value = getDriver().getCurrentUrl(); + localizedLogger.info("loc.browser.url.value", value); + return value; } /** @@ -147,8 +149,8 @@ public IBrowserTabNavigation tabs() { * @param timeout seconds to wait */ public void setPageLoadTimeout(Duration timeout) { - localizedLogger.debug("loc.browser.page.load.timeout", timeout.getSeconds()); if (!getBrowserName().equals(BrowserName.SAFARI)) { + localizedLogger.debug("loc.browser.page.load.timeout", timeout.getSeconds()); getDriver().manage().timeouts().pageLoadTimeout(timeout.getSeconds(), TimeUnit.SECONDS); } } @@ -160,8 +162,8 @@ public void setPageLoadTimeout(Duration timeout) { * @param timeout duration of time to wait */ public void setImplicitWaitTimeout(Duration timeout) { - localizedLogger.debug("loc.browser.implicit.timeout", timeout.getSeconds()); if (!timeout.equals(getImplicitWaitTimeout())) { + localizedLogger.debug("loc.browser.implicit.timeout", timeout.getSeconds()); getDriver().manage().timeouts().implicitlyWait(timeout.getSeconds(), TimeUnit.SECONDS); implicitTimeout = timeout; } @@ -184,6 +186,7 @@ public void setScriptTimeout(Duration timeout) { * Use setPageLoadTimeout to configure your own timeout from code if it is necessary */ public void waitForPageToLoad() { + localizedLogger.info("loc.browser.page.wait"); ExpectedCondition condition = d -> { Object result = executeScript(JavaScript.IS_PAGE_LOADED.getScript()); return result instanceof Boolean && (Boolean) result; @@ -305,9 +308,11 @@ public void handleAlert(AlertActions alertAction) { * @param text message to send */ public void handlePromptAlert(AlertActions alertAction, String text) { + localizedLogger.info(String.format("loc.browser.alert.%s", alertAction.name().toLowerCase())); try { Alert alert = getDriver().switchTo().alert(); if (text != null && !text.isEmpty()) { + localizedLogger.info("loc.send.text", text); getDriver().switchTo().alert().sendKeys(text); } if (alertAction.equals(AlertActions.ACCEPT)) { diff --git a/src/main/java/aquality/selenium/browser/BrowserFactory.java b/src/main/java/aquality/selenium/browser/BrowserFactory.java index 4625f23..696cbdf 100644 --- a/src/main/java/aquality/selenium/browser/BrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/BrowserFactory.java @@ -1,42 +1,42 @@ package aquality.selenium.browser; -import aquality.selenium.core.localization.ILocalizationManager; -import aquality.selenium.core.logging.Logger; +import aquality.selenium.configuration.IBrowserProfile; +import aquality.selenium.core.localization.ILocalizedLogger; import aquality.selenium.core.utilities.IActionRetrier; -import org.openqa.selenium.Capabilities; -import org.openqa.selenium.remote.CommandExecutor; +import org.openqa.selenium.SessionNotCreatedException; +import org.openqa.selenium.TimeoutException; +import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.remote.UnreachableBrowserException; -import java.util.Collections; +import java.util.Arrays; -interface BrowserFactory extends IBrowserFactory { +public abstract class BrowserFactory implements IBrowserFactory { - default IllegalArgumentException getLoggedWrongBrowserNameException() { - String message = AqualityServices.get(ILocalizationManager.class).getLocalizedMessage("loc.browser.name.wrong"); - IllegalArgumentException exception = new IllegalArgumentException(message); - Logger.getInstance().fatal(message, exception); - return exception; - } + private final IActionRetrier actionRetrier; + private final IBrowserProfile browserProfile; + private final ILocalizedLogger localizedLogger; - default void logBrowserIsReady(BrowserName browserName) { - AqualityServices.getLocalizedLogger().info("loc.browser.ready", browserName.toString()); - } + protected BrowserFactory(IActionRetrier actionRetrier, IBrowserProfile browserProfile, ILocalizedLogger localizedLogger) { - default T getDriver(Class driverClass, Capabilities capabilities) { - return getDriver(driverClass, null, capabilities); + this.actionRetrier = actionRetrier; + this.browserProfile = browserProfile; + this.localizedLogger = localizedLogger; } - default T getDriver(Class driverClass, CommandExecutor commandExecutor, Capabilities capabilities) { - return AqualityServices.get(IActionRetrier.class).doWithRetry(() -> { - try { - if (commandExecutor != null) { - return driverClass.getDeclaredConstructor(CommandExecutor.class, Capabilities.class).newInstance(commandExecutor, capabilities); - } - - return driverClass.getDeclaredConstructor(Capabilities.class).newInstance(capabilities); - } catch (ReflectiveOperationException e) { - throw new UnsupportedOperationException(String.format("Cannot instantiate driver with type '%1$s'.", driverClass), e); - } - }, Collections.emptyList()); + protected abstract RemoteWebDriver getDriver(); + + @Override + public Browser getBrowser() { + RemoteWebDriver driver = actionRetrier.doWithRetry( + this::getDriver, + Arrays.asList( + SessionNotCreatedException.class, + UnreachableBrowserException.class, + WebDriverException.class, + TimeoutException.class)); + Browser browser = new Browser(driver); + localizedLogger.info("loc.browser.ready", browserProfile.getBrowserName().toString()); + return browser; } } diff --git a/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java b/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java index 4d53d3f..218db86 100644 --- a/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/LocalBrowserFactory.java @@ -2,8 +2,11 @@ import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.driversettings.IDriverSettings; +import aquality.selenium.core.localization.ILocalizedLogger; +import aquality.selenium.core.utilities.IActionRetrier; import io.github.bonigarcia.wdm.Architecture; import io.github.bonigarcia.wdm.WebDriverManager; +import org.openqa.selenium.Capabilities; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.edge.EdgeDriver; import org.openqa.selenium.firefox.FirefoxDriver; @@ -11,16 +14,17 @@ import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.safari.SafariDriver; -public class LocalBrowserFactory implements BrowserFactory { +public class LocalBrowserFactory extends BrowserFactory { private final IBrowserProfile browserProfile; - public LocalBrowserFactory() { - this.browserProfile = AqualityServices.getBrowserProfile(); + public LocalBrowserFactory(IActionRetrier actionRetrier, IBrowserProfile browserProfile, ILocalizedLogger localizedLogger) { + super(actionRetrier, browserProfile, localizedLogger); + this.browserProfile = browserProfile; } @Override - public Browser getBrowser() { + protected RemoteWebDriver getDriver() { BrowserName browserName = browserProfile.getBrowserName(); RemoteWebDriver driver; IDriverSettings driverSettings = browserProfile.getDriverSettings(); @@ -47,10 +51,16 @@ public Browser getBrowser() { driver = getDriver(SafariDriver.class, driverSettings.getCapabilities()); break; default: - throw getLoggedWrongBrowserNameException(); + throw new IllegalArgumentException(String.format("Browser [%s] is not supported.", browserName)); } - logBrowserIsReady(browserName); + return driver; + } - return new Browser(driver); + private T getDriver(Class driverClass, Capabilities capabilities) { + try { + return driverClass.getDeclaredConstructor(Capabilities.class).newInstance(capabilities); + } catch (ReflectiveOperationException e) { + throw new UnsupportedOperationException(String.format("Cannot instantiate driver with type '%1$s'.", driverClass), e); + } } } diff --git a/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java b/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java index 1d05fbf..7324797 100644 --- a/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java +++ b/src/main/java/aquality/selenium/browser/RemoteBrowserFactory.java @@ -2,9 +2,11 @@ import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.ITimeoutConfiguration; -import aquality.selenium.configuration.driversettings.IDriverSettings; +import aquality.selenium.core.localization.ILocalizedLogger; +import aquality.selenium.core.utilities.IActionRetrier; import com.google.common.collect.ImmutableMap; import org.openqa.selenium.Capabilities; +import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.CommandExecutor; import org.openqa.selenium.remote.HttpCommandExecutor; import org.openqa.selenium.remote.LocalFileDetector; @@ -17,27 +19,24 @@ import java.time.Duration; -public class RemoteBrowserFactory implements BrowserFactory { +public class RemoteBrowserFactory extends BrowserFactory { private final IBrowserProfile browserProfile; private final ITimeoutConfiguration timeoutConfiguration; + private final ILocalizedLogger localizedLogger; - public RemoteBrowserFactory() { - browserProfile = AqualityServices.getBrowserProfile(); - timeoutConfiguration = AqualityServices.get(ITimeoutConfiguration.class); + public RemoteBrowserFactory(IActionRetrier actionRetrier, IBrowserProfile browserProfile, + ITimeoutConfiguration timeoutConfiguration, ILocalizedLogger localizedLogger) { + super(actionRetrier, browserProfile, localizedLogger); + this.browserProfile = browserProfile; + this.timeoutConfiguration = timeoutConfiguration; + this.localizedLogger = localizedLogger; } @Override - public Browser getBrowser() { - BrowserName browserName = browserProfile.getBrowserName(); - IDriverSettings driverSettings = browserProfile.getDriverSettings(); - logBrowserIsReady(browserName); - RemoteWebDriver driver = createRemoteDriver(driverSettings.getCapabilities()); - return new Browser(driver); - } - - private RemoteWebDriver createRemoteDriver(Capabilities capabilities) { - AqualityServices.getLocalizedLogger().info("loc.browser.grid"); + protected RemoteWebDriver getDriver() { + Capabilities capabilities = browserProfile.getDriverSettings().getCapabilities(); + localizedLogger.info("loc.browser.grid"); ClientFactory clientFactory = new ClientFactory(); CommandExecutor commandExecutor = new HttpCommandExecutor( @@ -45,9 +44,16 @@ private RemoteWebDriver createRemoteDriver(Capabilities capabilities) { browserProfile.getRemoteConnectionUrl(), clientFactory); - RemoteWebDriver driver = getDriver(RemoteWebDriver.class, commandExecutor, capabilities); - driver.setFileDetector(new LocalFileDetector()); - return driver; + try { + RemoteWebDriver driver = new RemoteWebDriver(commandExecutor, capabilities); + driver.setFileDetector(new LocalFileDetector()); + return driver; + } + catch (WebDriverException e) { + localizedLogger.fatal("loc.browser.grid.fail", e); + throw e; + } + } class ClientFactory implements Factory { diff --git a/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java index 2830af2..57db97e 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/ChromeSettings.java @@ -37,7 +37,6 @@ private void setChromePrefs(ChromeOptions options){ } private void setChromeArgs(ChromeOptions options) { - logStartArguments(); for (String arg : getBrowserStartArguments()) { options.addArguments(arg); } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java index 45b79b8..2ce04ca 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/DriverSettings.java @@ -5,12 +5,14 @@ import aquality.selenium.core.logging.Logger; import aquality.selenium.core.utilities.ISettingsFile; import io.github.bonigarcia.wdm.Architecture; +import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.PageLoadStrategy; import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +20,9 @@ abstract class DriverSettings implements IDriverSettings { private final ISettingsFile settingsFile; + private Map options; + private Map capabilities; + private List startArguments; protected DriverSettings(ISettingsFile settingsFile) { this.settingsFile = settingsFile; @@ -27,23 +32,51 @@ protected ISettingsFile getSettingsFile() { return settingsFile; } - Map getBrowserOptions() { - return getSettingsFile().getMap(getDriverSettingsPath(CapabilityType.OPTIONS)); - } - - private Map getBrowserCapabilities() { - return getSettingsFile().getMap(getDriverSettingsPath(CapabilityType.CAPABILITIES)); + protected Map getBrowserOptions() { + if (options == null) { + options = getMapOrEmpty(CapabilityType.OPTIONS); + } + return options; } - List getBrowserStartArguments() { - return getSettingsFile().getList(getDriverSettingsPath(CapabilityType.START_ARGS)); + protected Map getBrowserCapabilities() { + if (capabilities == null) { + capabilities = getMapOrEmpty(CapabilityType.CAPABILITIES); + } + return capabilities; + } + + private Map getMapOrEmpty(CapabilityType capabilityType) { + String path = getDriverSettingsPath(capabilityType); + Map map = getSettingsFile().isValuePresent(path) ? getSettingsFile().getMap(path) : Collections.emptyMap(); + logCollection("loc.browser.".concat(capabilityType.getKey()), map); + return map; + } + + protected List getBrowserStartArguments() { + if (startArguments == null) { + String path = getDriverSettingsPath(CapabilityType.START_ARGS); + boolean isValuePresent; + try { + getSettingsFile().getValue(path); + isValuePresent = true; + } + catch (IllegalArgumentException e) { + isValuePresent = false; + } + startArguments = isValuePresent ? getSettingsFile().getList(path) : Collections.emptyList(); + logCollection("loc.browser.arguments", startArguments); + } + return startArguments; } - void logStartArguments() { - List startArguments = getBrowserStartArguments(); - if (!startArguments.isEmpty()) { + @SafeVarargs + private final void logCollection(String messageKey, final T... elements) { + if (elements.length == 1 && + ((elements[0] instanceof Map && !((Map)elements[0]).isEmpty()) + || (elements[0] instanceof List && !((List)elements[0]).isEmpty()))) { AqualityServices.getLocalizedLogger() - .info("loc.browser.arguments.setting", String.join(" ", startArguments)); + .debug(messageKey,System.lineSeparator() + StringUtils.join(elements)); } } @@ -79,17 +112,16 @@ String getDriverSettingsPath(final String... paths) { } void setCapabilities(MutableCapabilities options) { - Map capabilities = getBrowserCapabilities(); - capabilities.forEach(options::setCapability); + getBrowserCapabilities().forEach(options::setCapability); } @Override public String getDownloadDir() { - Map options = getBrowserOptions(); + Map browserOptions = getBrowserOptions(); String key = getDownloadDirCapabilityKey(); - if (options.containsKey(key)) { - String pathInConfiguration = String.valueOf(options.get(key)); + if (browserOptions.containsKey(key)) { + String pathInConfiguration = String.valueOf(browserOptions.get(key)); return pathInConfiguration.contains(".") ? getAbsolutePath(pathInConfiguration) : pathInConfiguration; } throw new IllegalArgumentException(String.format("failed to find %s profiles option for %s", key, getBrowserName())); diff --git a/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java index 02d8d0e..ed757a0 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/FirefoxSettings.java @@ -48,7 +48,6 @@ private void setFirefoxPrefs(FirefoxOptions options) { } private void setFirefoxArgs(FirefoxOptions options) { - logStartArguments(); for (String arg : getBrowserStartArguments()) { options.addArguments(arg); } diff --git a/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java b/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java index c7d91fe..065b6cf 100644 --- a/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java +++ b/src/main/java/aquality/selenium/configuration/driversettings/IExplorerSettings.java @@ -15,6 +15,7 @@ public InternetExplorerOptions getCapabilities() { InternetExplorerOptions internetExplorerOptions = new InternetExplorerOptions(); setCapabilities(internetExplorerOptions); internetExplorerOptions.setPageLoadStrategy(getPageLoadStrategy()); + internetExplorerOptions.addCommandSwitches(getBrowserStartArguments().toArray(new String[0])); return internetExplorerOptions; } diff --git a/src/main/java/aquality/selenium/elements/CheckBox.java b/src/main/java/aquality/selenium/elements/CheckBox.java index 0ed4f8b..2889863 100644 --- a/src/main/java/aquality/selenium/elements/CheckBox.java +++ b/src/main/java/aquality/selenium/elements/CheckBox.java @@ -8,7 +8,7 @@ /** * Class describing the checkbox */ -public class CheckBox extends Element implements ICheckBox { +public class CheckBox extends CheckableElement implements ICheckBox { protected CheckBox(final By locator, final String name, final ElementState state) { super(locator, name, state); @@ -28,14 +28,9 @@ public void uncheck() { setState(false); } - @Override - public boolean isChecked() { - return getState(); - } - @Override public void toggle() { - setState(!isChecked()); + setState(!getState()); } @Override @@ -54,9 +49,4 @@ private void setState(boolean state) { click(); } } - - private boolean getState() { - logElementAction("loc.checkbox.get.state"); - return getElement().isSelected(); - } } diff --git a/src/main/java/aquality/selenium/elements/CheckableElement.java b/src/main/java/aquality/selenium/elements/CheckableElement.java new file mode 100644 index 0000000..572daa1 --- /dev/null +++ b/src/main/java/aquality/selenium/elements/CheckableElement.java @@ -0,0 +1,28 @@ +package aquality.selenium.elements; + +import aquality.selenium.core.elements.ElementState; +import org.openqa.selenium.By; + +public abstract class CheckableElement extends Element { + /** + * The main constructor + * + * @param loc By Locator + * @param nameOf Output in logs + * @param stateOf desired ElementState + */ + protected CheckableElement(By loc, String nameOf, ElementState stateOf) { + super(loc, nameOf, stateOf); + } + + public boolean isChecked() { + logElementAction("loc.checkable.get.state"); + boolean state = getState(); + logElementAction("loc.checkable.state", state); + return state; + } + + protected boolean getState() { + return doWithRetry(() -> getElement().isSelected()); + } +} diff --git a/src/main/java/aquality/selenium/elements/ComboBox.java b/src/main/java/aquality/selenium/elements/ComboBox.java index ebb6a3f..39459ec 100644 --- a/src/main/java/aquality/selenium/elements/ComboBox.java +++ b/src/main/java/aquality/selenium/elements/ComboBox.java @@ -30,7 +30,7 @@ protected String getElementType() { @Override public void selectByIndex(int index) { - logElementAction(LOG_SELECTING_VALUE); + logElementAction(LOG_SELECTING_VALUE, String.format("#%s", index)); doWithRetry(() -> new Select(getElement()).selectByIndex(index)); } @@ -48,7 +48,7 @@ public void clickAndSelectByText(String value) { @Override public void selectByContainingText(String text) { - logElementAction(LOG_SELECTING_VALUE); + logElementAction("loc.combobox.select.by.text", text); selectOptionThatContains(WebElement::getText, Select::selectByVisibleText, text); @@ -56,7 +56,7 @@ public void selectByContainingText(String text) { @Override public void selectByContainingValue(String value) { - logElementAction(LOG_SELECTING_VALUE); + logElementAction(LOG_SELECTING_VALUE, value); selectOptionThatContains(element -> element.getAttribute(Attributes.VALUE.toString()), Select::selectByValue, value); @@ -84,7 +84,7 @@ private void selectOptionThatContains(Function getValueFunc, @Override public void selectByValue(String value) { - logElementAction(LOG_SELECTING_VALUE); + logElementAction(LOG_SELECTING_VALUE, value); doWithRetry(() -> new Select(getElement()).selectByValue(value)); } @@ -96,33 +96,46 @@ public void clickAndSelectByValue(String value) { @Override public String getSelectedValue() { - return doWithRetry( + logElementAction("loc.combobox.getting.selected.value"); + String value = doWithRetry( () -> new Select(getElement()).getFirstSelectedOption().getAttribute(Attributes.VALUE.toString())); + logElementAction("loc.combobox.selected.value", value); + return value; } @Override public String getSelectedText() { - return doWithRetry(() -> new Select(getElement()).getFirstSelectedOption().getText()); + logElementAction("loc.combobox.getting.selected.text"); + String text = doWithRetry(() -> new Select(getElement()).getFirstSelectedOption().getText()); + logElementAction("loc.combobox.selected.text", text); + return text; } @Override public List getValues() { logElementAction("loc.combobox.get.values"); - return doWithRetry(() -> + List values = doWithRetry(() -> new Select(getElement()).getOptions() .stream() .map(option -> option.getAttribute(Attributes.VALUE.toString())) .collect(Collectors.toList())); + logElementAction("loc.combobox.values", + values.stream().map(value -> String.format("'%s'", value)).collect(Collectors.joining(", "))); + return values; } @Override public List getTexts() { logElementAction("loc.combobox.get.texts"); - return doWithRetry(() -> + List values = doWithRetry(() -> new Select(getElement()).getOptions() .stream() .map(WebElement::getText) .collect(Collectors.toList())); + + logElementAction("loc.combobox.texts", + values.stream().map(value -> String.format("'%s'", value)).collect(Collectors.joining(", "))); + return values; } @Override diff --git a/src/main/java/aquality/selenium/elements/Element.java b/src/main/java/aquality/selenium/elements/Element.java index 9462b09..bd85f5e 100644 --- a/src/main/java/aquality/selenium/elements/Element.java +++ b/src/main/java/aquality/selenium/elements/Element.java @@ -115,28 +115,34 @@ public String getText() { public String getText(HighlightState highlightState) { logElementAction("loc.get.text"); getJsActions().highlightElement(); - return doWithRetry(() -> getElement().getText()); + String value = doWithRetry(() -> getElement().getText()); + logElementAction("loc.text.value", value); + return value; } @Override public IElementStateProvider state() { return getElementCacheConfiguration().isEnabled() - ? new CachedElementStateProvider(getLocator(), getConditionalWait(), getCache(), getLocalizedLogger()) - : new ElementStateProvider(getLocator(), getConditionalWait(), getElementFinder()); + ? new CachedElementStateProvider(getLocator(), getConditionalWait(), getCache(), logElementState()) + : new ElementStateProvider(getLocator(), getConditionalWait(), getElementFinder(), logElementState()); } @Override public String getAttribute(final String attr, HighlightState highlightState) { logElementAction("loc.el.getattr", attr); getJsActions().highlightElement(); - return doWithRetry(() -> getElement().getAttribute(attr)); + String value = doWithRetry(() -> getElement().getAttribute(attr)); + logElementAction("loc.el.attr.value", attr, value); + return value; } @Override public String getCssValue(final String propertyName, HighlightState highlightState) { logElementAction("loc.el.cssvalue", propertyName); getJsActions().highlightElement(); - return doWithRetry(() -> getElement().getCssValue(propertyName)); + String value = doWithRetry(() -> getElement().getCssValue(propertyName)); + logElementAction("loc.el.attr.value", propertyName, value); + return value; } @Override @@ -167,7 +173,7 @@ public T findChildElement(By childLoc, String name, Element @Override public void sendKeys(Keys key) { - logElementAction("loc.text.sending.keys", Keys.class.getSimpleName().concat(".").concat(key.name())); + logElementAction("loc.text.sending.key", Keys.class.getSimpleName().concat(".").concat(key.name())); doWithRetry(() -> getElement().sendKeys(key)); } } diff --git a/src/main/java/aquality/selenium/elements/ElementStateProvider.java b/src/main/java/aquality/selenium/elements/ElementStateProvider.java index 561f88a..482328a 100644 --- a/src/main/java/aquality/selenium/elements/ElementStateProvider.java +++ b/src/main/java/aquality/selenium/elements/ElementStateProvider.java @@ -1,73 +1,21 @@ package aquality.selenium.elements; -import aquality.selenium.browser.AqualityServices; import aquality.selenium.core.elements.DefaultElementStateProvider; -import aquality.selenium.core.elements.ElementState; import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.elements.interfaces.ILogElementState; import aquality.selenium.core.waitings.IConditionalWait; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import java.time.Duration; - public class ElementStateProvider extends DefaultElementStateProvider { - private static final String WAIT_FOR_STATE_KEY = "loc.waitinstate"; - private final By locator; - - public ElementStateProvider(By locator, IConditionalWait conditionalWait, IElementFinder elementFinder) { - super(locator, conditionalWait, elementFinder); - this.locator = locator; - } - - private void logLocInfo(String key, Object... args) { - AqualityServices.getLocalizedLogger().info(key, args); + public ElementStateProvider(By locator, IConditionalWait conditionalWait, IElementFinder elementFinder, + ILogElementState logger) { + super(locator, conditionalWait, elementFinder, logger); } @Override protected boolean isElementEnabled(WebElement element) { return element.isEnabled() && !element.getAttribute(Attributes.CLASS.toString()).contains("disabled"); } - - @Override - public void waitForClickable(Duration timeout) { - logLocInfo(WAIT_FOR_STATE_KEY, elementClickable().getStateName(), locator); - super.waitForClickable(timeout); - } - - @Override - public boolean waitForDisplayed(Duration timeout) { - logLocInfo(WAIT_FOR_STATE_KEY, ElementState.DISPLAYED, locator); - return super.waitForDisplayed(timeout); - } - - @Override - public boolean waitForNotDisplayed(Duration timeout) { - logLocInfo("loc.waitinvisible", locator); - return super.waitForNotDisplayed(timeout); - } - - @Override - public boolean waitForExist(Duration timeout) { - logLocInfo("loc.waitexists", locator); - return super.waitForExist(timeout); - } - - @Override - public boolean waitForNotExist(Duration timeout) { - logLocInfo("loc.waitnotexists", locator); - return super.waitForNotExist(timeout); - } - - @Override - public boolean waitForEnabled(Duration timeout) { - logLocInfo(WAIT_FOR_STATE_KEY, elementEnabled().getStateName(), locator); - return super.waitForEnabled(timeout); - } - - @Override - public boolean waitForNotEnabled(Duration timeout) { - logLocInfo(WAIT_FOR_STATE_KEY, elementNotEnabled().getStateName(), locator); - return super.waitForNotEnabled(timeout); - } } diff --git a/src/main/java/aquality/selenium/elements/Link.java b/src/main/java/aquality/selenium/elements/Link.java index eadeafb..07e86bb 100644 --- a/src/main/java/aquality/selenium/elements/Link.java +++ b/src/main/java/aquality/selenium/elements/Link.java @@ -19,6 +19,6 @@ protected String getElementType() { @Override public String getHref() { - return getAttribute("href"); + return getAttribute("href", HighlightState.DEFAULT); } } diff --git a/src/main/java/aquality/selenium/elements/RadioButton.java b/src/main/java/aquality/selenium/elements/RadioButton.java index 8a0b4a0..6c4523f 100644 --- a/src/main/java/aquality/selenium/elements/RadioButton.java +++ b/src/main/java/aquality/selenium/elements/RadioButton.java @@ -7,7 +7,7 @@ /** * Class describing the Radiobutton */ -public class RadioButton extends Element implements IRadioButton { +public class RadioButton extends CheckableElement implements IRadioButton { protected RadioButton(final By locator, final String name, final ElementState state) { super(locator, name, state); @@ -16,9 +16,4 @@ protected RadioButton(final By locator, final String name, final ElementState st protected String getElementType() { return getLocalizationManager().getLocalizedMessage("loc.radio"); } - - @Override - public boolean isChecked() { - return doWithRetry(() -> getElement().isSelected()); - } } diff --git a/src/main/java/aquality/selenium/elements/TextBox.java b/src/main/java/aquality/selenium/elements/TextBox.java index b2435c9..93a4243 100644 --- a/src/main/java/aquality/selenium/elements/TextBox.java +++ b/src/main/java/aquality/selenium/elements/TextBox.java @@ -49,7 +49,7 @@ public void submit() { @Override public String getValue() { - return getAttribute(Attributes.VALUE.toString()); + return getAttribute(Attributes.VALUE.toString(), HighlightState.DEFAULT); } @Override diff --git a/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java b/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java index 82e9412..507989e 100644 --- a/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java +++ b/src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java @@ -12,14 +12,6 @@ public CheckBoxJsActions(ICheckBox checkBox, String elementType) { super(checkBox, elementType); } - /** - * @return state of checkbox using .checked property of element - */ - public boolean getState() { - logElementAction("loc.checkbox.get.state"); - return Boolean.valueOf(executeScript(JavaScript.GET_CHECKBOX_STATE, element).toString()); - } - /** * Performs check action on the element. */ @@ -39,14 +31,17 @@ public void uncheck() { * @return true if checked, false otherwise */ public boolean isChecked() { - return getState(); + logElementAction("loc.checkable.get.state"); + boolean state = getState(); + logElementAction("loc.checkable.state", state); + return state; } /** * Performs toggle action on the element. */ public void toggle() { - setState(!isChecked()); + setState(!getState()); } /** @@ -60,4 +55,11 @@ private void setState(boolean state) { click(); } } + + /** + * @return state of checkbox using .checked property of element + */ + private boolean getState() { + return Boolean.valueOf(executeScript(JavaScript.GET_CHECKBOX_STATE, element).toString()); + } } \ No newline at end of file diff --git a/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java b/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java index 78682e8..7b1d1b2 100644 --- a/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java +++ b/src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java @@ -4,6 +4,7 @@ import aquality.selenium.elements.interfaces.IComboBox; import java.util.List; +import java.util.stream.Collectors; public class ComboBoxJsActions extends JsActions { @@ -18,7 +19,10 @@ public ComboBoxJsActions(IComboBox comboBox, String elementType) { */ public List getTexts() { logElementAction("loc.combobox.get.texts.js"); - return (List) executeScript(JavaScript.GET_COMBOBOX_TEXTS, element); + List values = (List) executeScript(JavaScript.GET_COMBOBOX_TEXTS, element); + logElementAction("loc.combobox.texts", + values.stream().map(value -> String.format("'%s'", value)).collect(Collectors.joining(", "))); + return values; } /** @@ -28,7 +32,9 @@ public List getTexts() { */ public String getSelectedText() { logElementAction("loc.combobox.get.text.js"); - return (String) executeScript(JavaScript.GET_COMBOBOX_SELECTED_TEXT, element); + String text = (String) executeScript(JavaScript.GET_COMBOBOX_SELECTED_TEXT, element); + logElementAction("loc.combobox.selected.text", text); + return text; } /** diff --git a/src/main/java/aquality/selenium/elements/actions/JsActions.java b/src/main/java/aquality/selenium/elements/actions/JsActions.java index 8e262e3..675ab53 100644 --- a/src/main/java/aquality/selenium/elements/actions/JsActions.java +++ b/src/main/java/aquality/selenium/elements/actions/JsActions.java @@ -108,7 +108,9 @@ public void setFocus() { */ public boolean isElementOnScreen() { logElementAction("loc.is.present.js"); - return (boolean) executeScript(JavaScript.ELEMENT_IS_ON_SCREEN, element); + boolean value = (boolean) executeScript(JavaScript.ELEMENT_IS_ON_SCREEN, element); + logElementAction("loc.is.present.value", value); + return value; } /** @@ -147,7 +149,9 @@ public Point getViewPortCoordinates() { */ public String getXPath() { logElementAction("loc.get.xpath.js"); - return (String) executeScript(JavaScript.GET_ELEMENT_XPATH, element); + String value = (String) executeScript(JavaScript.GET_ELEMENT_XPATH, element); + logElementAction("loc.xpath.value", value); + return value; } protected Object executeScript(JavaScript javaScript, IElement element) { diff --git a/src/main/java/aquality/selenium/forms/Form.java b/src/main/java/aquality/selenium/forms/Form.java index 03b7eae..0e83afb 100644 --- a/src/main/java/aquality/selenium/forms/Form.java +++ b/src/main/java/aquality/selenium/forms/Form.java @@ -1,6 +1,7 @@ package aquality.selenium.forms; import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.elements.interfaces.IElementStateProvider; import aquality.selenium.core.localization.ILocalizedLogger; import aquality.selenium.elements.interfaces.IElementFactory; import aquality.selenium.elements.interfaces.ILabel; @@ -47,13 +48,23 @@ public String getName() { } /** - * Return form state for form locator + * Provides ability to get form's state (whether it is displayed, exists or not) and respective waiting functions. + * @return state provider of the current form. + */ + public IElementStateProvider state() { + return getFormLabel().state(); + } + + /** + * @deprecated This method will be removed in the future release. Use state().waitForDisplayed() if needed. + * Return form state for form locator, waiting for the form to be displayed. * * @return True - form is opened, * False - form is not opened */ + @Deprecated public boolean isDisplayed() { - return getFormLabel().state().waitForDisplayed(); + return state().waitForDisplayed(); } /** diff --git a/src/main/resources/localization/be.json b/src/main/resources/localization/be.json index 24c6f10..e9a20dd 100644 --- a/src/main/resources/localization/be.json +++ b/src/main/resources/localization/be.json @@ -1,47 +1,61 @@ { - "loc.browser.arguments.setting" : "Задаем стартавыя аргументы браўзэра з JSON файла: %s", + "loc.browser.arguments" : "Атрымалі стартавыя аргументы браўзэра з settings файла: %s", "loc.browser.back" : "Вяртаемся да папярэдняй старонкі", "loc.browser.forward" : "Пераходзім да наступнай старонкі", - "loc.browser.caps.setting" : "Задаем capabilities браўзэра з JSON файла: %s", - "loc.browser.config.setting" : "Задаем опцыі профіля браўзэра з JSON файла: %s", + "loc.browser.capabilities" : "Атрымалі capabilities браўзэра з settings файла: %s", + "loc.browser.options" : "Атрымалі опцыі профіля браўзэра з settings файла: %s", "loc.browser.driver.quit" : "Закрываем браўзэр", "loc.browser.getUrl" : "Атрымліваем адрас бягучай старонкі", + "loc.browser.url.value": "Адрас бягучай старонкі: [%s]", "loc.browser.grid" : "Усталёўваем драйвэр для браўзэра з Selenium Grid hub", "loc.browser.grid.fail" : "Не ўдалося ўсталяваць драйвэр браўзэра з Selenium Grid hub", "loc.browser.maximize" : "Разгортваем акно браўзэра на ўвесь экран", - "loc.browser.name.wrong" : "Няслушнае імя браўзэра.", - "loc.browser.navigate" : "Пераходзім па адрасу - '%s'", + "loc.browser.navigate" : "Пераходзім па адрасе - '%s'", + "loc.browser.page.wait": "Чакаем загрузкі старонкі", "loc.browser.page.timeout" : "Таймаўт загрузкі старонкі", "loc.browser.ready" : "Браўзэр '%1$s' гатовы...", "loc.browser.refresh" : "Абнаўляем старонку", "loc.browser.page.load.timeout" : "Задаем таймаўт загрузкі старонкі: '%1$s' сек.", "loc.browser.implicit.timeout" : "Задаем implicit(няяўны) таймаўт: '%1$s' сек.", "loc.browser.script.timeout" : "Задаем таймаўт на выкананне асінхронных javascript камандаў: '%1$s' сек.", + "loc.browser.alert.accept" : "Пацвярджаем дзеянне ў акне апавяшчэння", + "loc.browser.alert.decline" : "Адхіляем дзеянне ў акне апавяшчэння", "loc.browser.alert.fail" : "Памылка пры ўзаемадзеянні з акном апавяшчэння", "loc.button" : "Кнопка", "loc.checkbox" : "Чэкбокс", - "loc.checkbox.get.state" : "Атрымліваем стан", + "loc.checkable.get.state" : "Атрымліваем стан", + "loc.checkable.state": "Стан: [%s]", "loc.clicking" : "Націскаем", "loc.clicking.double" : "Падвойна націскаем", "loc.clicking.js" : "Націскаем праз Javascript", "loc.clicking.right" : "Націскаем правай кнопкай", "loc.combobox" : "Камбабокс", + "loc.combobox.getting.selected.text": "Атрымліваем выбраны тэкст", + "loc.combobox.getting.selected.value": "Атрымліваем выбранае значэнне", + "loc.combobox.selected.text": "Выбраны тэкст: [%s]", + "loc.combobox.selected.value": "Выбранае значэнне: [%s]", "loc.combobox.select.by.text" : "Выбіраем значэнне з тэкстам '%s'", "loc.combobox.select.by.text.js": "Выбіраем значэнне з тэкстам '%s' праз JavaScript", "loc.combobox.get.texts": "Атрымліваем спіс тэкстаў опцыяў", "loc.combobox.get.texts.js": "Атрымліваем спіс тэкстаў опцыяў праз JavaScript", "loc.combobox.get.values" : "Атрымліваем спіс значэнняў", "loc.combobox.get.text.js": "Атрымліваем выбраны тэкст праз JavaScript", + "loc.combobox.texts": "Спіс тэкстаў опцыяў: [%s]", + "loc.combobox.values": "Спіс значэнняў: [%s]", "loc.combobox.impossible.to.select.contain.value.or.text" : "Немагчыма выбраць опцыю, якая змяшчае значэнне/тэкст '%1$s' у камбабоксе '%2$s'", "loc.el.getattr" : "Атрымліваем атрыбут '%1$s'", + "loc.el.attr.value": "Значэнне атрыбута '%1$s': [%2$s]", "loc.el.cssvalue" : "Атрымліваем значэнне css '%1$s'", "loc.file.reading_exception" : "Памылка пры чытанні файла: '%s'", "loc.focusing" : "Факусуемся", "loc.get.text" : "Атрымліваем тэкст элемента", + "loc.text.value": "Тэкст элемента: [%1$s]", "loc.get.text.js" : "Атрымліваем тэкст элемента праз Javascript", "loc.hover.js" : "Наводзім курсор мышы на элемент праз JavaScript", "loc.is.present.js" : "Вызначаем, ці прысутны элемент на экране, праз JavaScript", + "loc.is.present.value": "Ці прысутны элемент на экране: [%s]", "loc.get.xpath.js": "Атрымліваем XPath лакатар элемента праз JavaScript", + "loc.xpath.value": "XPath лакатар: [%s]", "loc.label" : "Надпіс", "loc.link" : "Спасылка", "loc.moving" : "Наводзім курсор мышы на элемент", @@ -49,26 +63,15 @@ "loc.radio" : "Радыёкнопка", "loc.scrolling.center.js" : "Пракручваем старонку да цэнтра элемента праз JavaScript", "loc.scrolling.js" : "Пракручваем старонку праз JavaScript", - "loc.selecting.value" : "Выбіраем значэнне", + "loc.selecting.value" : "Выбіраем значэнне - '%s'", "loc.send.text" : "Задаем тэкст - '%s'", - "loc.setting.value" : "Задаем значэнне '%s'", + "loc.setting.value" : "Задаем значэнне - '%s'", "loc.text.clearing" : "Ачышчаем", + "loc.text.submitting": "Адпраўляем", "loc.text.field" : "Тэкставае поле", - "loc.text.sending.keys" : "Націскаем клавішы '%1$s'", + "loc.text.sending.key" : "Націскаем клавішу '%1$s'", "loc.text.typing" : "Уводзім '%s'", "loc.text.masked_value" : "********", - "loc.wait.timeout.condition": "Не дачакаліся ўмовы '%2$s' цягам %1$s сек.", - "loc.waitexists" : "Чакаем прысутнасці элемента ў DOM па лакатару: %1$s", - "loc.waitinstate" : "Чакаем прысутнасці элемента ў стане %1$s па лакатару: %2$s", - "loc.waitinvisible" : "Чакаем адсутнасці элемента па лакатару: %1$s", - "loc.waitnotexists" : "Чакаем адсутнасці элемента ў DOM па лакатару: %1$s", - "loc.no.elements.found.in.state" : "Не знайшлі элементаў па лакатару '%1$s' у %2$s стане", - "loc.no.elements.found.by.locator" : "Не знайшлі элементаў па лакатару '%1$s'", - "loc.elements.were.found.but.not.in.state": "Знайшлі элементы па лакатару '%1$s', але яны не ў жаданым стане %2$s", - "loc.elements.found.but.should.not": "Не павінна быць знойдзена элементаў па лакатару '%1$s' у %2$s стане", - "loc.search.of.elements.failed": "Пошук элемента па лакатару '%1$s' прайшоў няўдала", - "loc.element.not.in.state": "Элемент %1$s не стаў %2$s пасля таймаўта %3$s", - "loc.get.page.source.failed": "Адбылася памылка ў час атрымання разметкі старонкі", "loc.browser.switch.to.tab.handle": "Пераключэнне на новую ўкладку па дэскрыптару '%1$s'", "loc.browser.switch.to.tab.index": "Пераключэнне на новую ўкладку па індэксе '%1$s'", "loc.browser.switch.to.new.tab": "Пераключэнне на новую ўкладку", diff --git a/src/main/resources/localization/en.json b/src/main/resources/localization/en.json index b73f55d..36c9e8c 100644 --- a/src/main/resources/localization/en.json +++ b/src/main/resources/localization/en.json @@ -1,47 +1,61 @@ { - "loc.browser.arguments.setting" : "Setting browser start arguments from JSON file: %s", + "loc.browser.arguments" : "Got browser start arguments from settings file: %s", "loc.browser.back" : "Return to previous page", "loc.browser.forward" : "Proceed to the next page", - "loc.browser.caps.setting" : "Setting browser capabilities from JSON file: %s", - "loc.browser.config.setting" : "Setting browser profile options from JSON file: %s", + "loc.browser.capabilities" : "Got browser capabilities from settings file: %s", + "loc.browser.options" : "Got browser profile options from settings file: %s", "loc.browser.driver.quit" : "Closing browser", "loc.browser.getUrl" : "Getting current url", + "loc.browser.url.value": "Current url: [%s]", "loc.browser.grid" : "Setting webdriver from selenium grid hub", - "loc.browser.grid.fail" : "Driver setting from Selenium Grid hub was failed", + "loc.browser.grid.fail" : "Driver setting from Selenium Grid hub was failed", "loc.browser.maximize" : "Maximizing browser window", - "loc.browser.name.wrong" : "Browser name is wrong.", "loc.browser.navigate" : "Navigate to url - '%s'", + "loc.browser.page.wait": "Waiting for page to load", "loc.browser.page.timeout" : "Page loading timed out", "loc.browser.ready" : "Browser '%1$s' ready...", "loc.browser.refresh" : "Refreshing the page", "loc.browser.page.load.timeout" : "Set '%1$s' timeout in seconds for loading of pages", "loc.browser.implicit.timeout" : "Set implicit timeout '%1$s' in seconds", "loc.browser.script.timeout" : "Set async javascript execution timeout '%1$s' in seconds", + "loc.browser.alert.accept" : "Accepting browser alert", + "loc.browser.alert.decline" : "Dismissing browser alert", "loc.browser.alert.fail" : "Failed while handling alert", "loc.button" : "Button", "loc.checkbox" : "CheckBox", - "loc.checkbox.get.state" : "Getting state", + "loc.checkable.get.state" : "Getting state", + "loc.checkable.state": "State: [%s]", "loc.clicking" : "Clicking", "loc.clicking.double" : "Clicking double", "loc.clicking.js" : "Clicking via Javascript", "loc.clicking.right" : "Clicking right", "loc.combobox" : "ComboBox", + "loc.combobox.getting.selected.text": "Getting selected text", + "loc.combobox.getting.selected.value": "Getting selected value", + "loc.combobox.selected.text": "Selected text: [%s]", + "loc.combobox.selected.value": "Selected value: [%s]", "loc.combobox.select.by.text" : "Selecting value by text '%s'", "loc.combobox.select.by.text.js": "Selecting value by text '%s' via JavaScript", "loc.combobox.get.texts": "Getting option texts array", "loc.combobox.get.texts.js": "Getting option texts array via JavaScript", "loc.combobox.get.values" : "Getting values array", "loc.combobox.get.text.js": "Getting selected text via JavaScript", + "loc.combobox.texts": "Option texts: [%s]", + "loc.combobox.values": "Option values: [%s]", "loc.combobox.impossible.to.select.contain.value.or.text" : "It is impossible to select option that contains value/text '%1$s' from combobox '%2$s'", "loc.el.getattr" : "Getting attribute '%1$s'", + "loc.el.attr.value": "Value of attribute '%1$s': [%2$s]", "loc.el.cssvalue" : "Getting css value '%1$s'", "loc.file.reading_exception" : "Exception while reading file: '%s'", "loc.focusing" : "Focusing", "loc.get.text" : "Getting text from element", + "loc.text.value": "Element's text: [%1$s]", "loc.get.text.js" : "Getting text from element via Javascript", "loc.hover.js" : "Hover mouse over element via JavaScript", "loc.is.present.js" : "Is present via JavaScript", + "loc.is.present.value": "Is present on screen: [%s]", "loc.get.xpath.js": "Getting XPath locator of element via JavaScript", + "loc.xpath.value": "XPath locator: [%s]", "loc.label" : "Label", "loc.link" : "Link", "loc.moving" : "Moving mouse to element", @@ -49,26 +63,15 @@ "loc.radio" : "RadioButton", "loc.scrolling.center.js" : "Scrolling to the center via JavaScript", "loc.scrolling.js" : "Scrolling via JavaScript", - "loc.selecting.value" : "Selecting value", + "loc.selecting.value" : "Selecting value - '%s'", "loc.send.text" : "Setting text - '%s'", - "loc.setting.value" : "Setting value '%s'", + "loc.setting.value" : "Setting value - '%s'", "loc.text.clearing" : "Clearing", + "loc.text.submitting": "Submitting", "loc.text.field" : "Text Field", - "loc.text.sending.keys" : "Sending keys '%s'", + "loc.text.sending.key" : "Sending key '%s'", "loc.text.typing" : "Typing '%s'", "loc.text.masked_value" : "********", - "loc.wait.timeout.condition": "Timed out after %1$s seconds during wait for condition '%2$s'", - "loc.waitexists" : "Wait until element exists in DOM using \"locator\": %1$s", - "loc.waitinstate" : "Wait until is present in state %1$s using \"locator\": %2$s", - "loc.waitinvisible" : "Wait until element is not visible using \"locator\": %1$s", - "loc.waitnotexists" : "Wait until element does not exist in DOM using \"locator\": %1$s", - "loc.no.elements.found.in.state" : "No elements with locator '%1$s' found in state '%2$s'", - "loc.no.elements.found.by.locator" : "No elements were found by locator '%1$s'", - "loc.elements.were.found.but.not.in.state" : "Elements were found by locator '%1$s' but not in desired state. %2$s", - "loc.elements.found.but.should.not": "No elements should be found by locator '%1$s' in %2$s state", - "loc.search.of.elements.failed": "Search of element by locator '%1$s' failed", - "loc.element.not.in.state": "Element %1$s has not become %2$s after timeout %3$s", - "loc.get.page.source.failed": "An exception occurred while tried to save the page source", "loc.browser.switch.to.tab.handle": "Switching to tab by handle '%1$s'", "loc.browser.switch.to.tab.index": "Switching to tab by index '%1$s'", "loc.browser.switch.to.new.tab": "Switching to new tab", diff --git a/src/main/resources/localization/ru.json b/src/main/resources/localization/ru.json index 12b2cb8..1c1bfa7 100644 --- a/src/main/resources/localization/ru.json +++ b/src/main/resources/localization/ru.json @@ -1,74 +1,77 @@ { - "loc.browser.arguments.setting" : "Установка стартовых аргументов браузера из JSON файла: %s", + "loc.browser.arguments" : "Получили стартовые аргументы браузера из settings файла: %s", "loc.browser.back" : "Возврат на предыдущую страницу", "loc.browser.forward" : "Перейти на следующую страницу", - "loc.browser.caps.setting" : "Установка capabilities браузера из JSON файла: %s", - "loc.browser.config.setting" : "Установка настроек браузера из JSON файла: %s", + "loc.browser.capabilities" : "Получили capabilities браузера из settings файла: %s", + "loc.browser.options" : "Получили опции профиля браузера из settings файла: %s", "loc.browser.driver.quit" : "Закрытие драйвера браузера", - "loc.browser.getUrl" : "Получение ссылки текущей страницы", + "loc.browser.getUrl" : "Получение адреса текущей страницы", + "loc.browser.url.value": "Адрес текущей страницы: [%s]", "loc.browser.grid" : "Установка драйвера браузера из Selenium Grid хаба", "loc.browser.grid.fail" : "Ошибка при получении драйвера из Selenium Grid хаба", "loc.browser.maximize" : "Открытие браузера на всё окно", - "loc.browser.name.wrong" : "Неверное имя браузера.", "loc.browser.navigate" : "Переход на страницу - '%s'", + "loc.browser.page.wait": "Ожидание загрузки страницы", "loc.browser.page.timeout" : "Таймаут загрузки страницы", "loc.browser.ready" : "Браузер '%1$s' готов...", "loc.browser.refresh" : "Обновление страницы", "loc.browser.page.load.timeout" : "Установка таймаута для загрузки страниц: '%1$s' секунд", "loc.browser.implicit.timeout" : "Установка implicit(неявного) таймаута: '%1$s' секунд", "loc.browser.script.timeout" : "Установка таймаута на выполнение асинхронных javascript вызовов: '%1$s' секунд", + "loc.browser.alert.accept" : "Подтверждение действия во всплывающем окне", + "loc.browser.alert.decline" : "Отклонение действия во всплывающем окне", "loc.browser.alert.fail" : "Не удалось обработать всплывающее окно", "loc.button" : "Кнопка", "loc.checkbox" : "Чекбокс", - "loc.checkbox.get.state" : "Получение состояния", + "loc.checkable.get.state" : "Получение состояния", + "loc.checkable.state": "Состояние: [%s]", "loc.clicking" : "Клик", "loc.clicking.double" : "Двойной Клик", "loc.clicking.js" : "Клик через Javascript", "loc.clicking.right" : "Клик правой кнопкой", "loc.combobox" : "Комбобокс", + "loc.combobox.getting.selected.text": "Получаем выбранный текст", + "loc.combobox.getting.selected.value": "Получаем выбранное значение", + "loc.combobox.selected.text": "Выбранный текст: [%s]", + "loc.combobox.selected.value": "Выбранное значение: [%s]", "loc.combobox.select.by.text" : "Выбор значения с текстом '%s'", "loc.combobox.select.by.text.js": "Выбор значения с текстом '%s' посредством JavaScript", "loc.combobox.get.texts": "Получение списка текстов опций", "loc.combobox.get.texts.js": "Получение списка текстов опций посредством JavaScript", "loc.combobox.get.values" : "Получение списка значений", "loc.combobox.get.text.js": "Получение текста выбранного значения посредством JavaScript", + "loc.combobox.texts": "Список текстов опций: [%s]", + "loc.combobox.values": "Список значений: [%s]", "loc.combobox.impossible.to.select.contain.value.or.text" : "Не удаётся выбрать значение которое содержит значение/текст '%1$s' в выпадающем списке '%2$s'", "loc.el.getattr" : "Получение аттрибута '%1$s'", + "loc.el.attr.value": "Значение аттрибута '%1$s'': [%2$s]", "loc.el.cssvalue" : "Получение значения css '%1$s'", "loc.file.reading_exception" : "Исключение при чтении файла: '%s'%n", "loc.focusing" : "Взятие элемента в фокус", "loc.get.text" : "Получение текста элемента", - "loc.get.text.js" : "Получение текста элемента (при помощи JavaScript)", - "loc.hover.js" : "Наведение курсора на элемент (при помощи JavaScript)", - "loc.is.present.js" : "Присутствует (с помощью JavaScript)", - "loc.get.xpath.js": "Получение XPath локатора элемента (при помощи JavaScript)", + "loc.text.value": "Текст элемента: [%1$s]", + "loc.get.text.js" : "Получение текста элемента (посредством JavaScript)", + "loc.hover.js" : "Наведение курсора на элемент (посредством JavaScript)", + "loc.is.present.js" : "Присутствует ли (посредством JavaScript)", + "loc.is.present.value": "Присутствует ли на экране: [%s]", + "loc.get.xpath.js": "Получение XPath локатора элемента (посредством JavaScript)", + "loc.xpath.value": "XPath локатор: [%s]", "loc.label" : "Надпись", "loc.link" : "Ссылка", "loc.moving" : "Наведение курсора на элемент", "loc.movingFrom" : "Сдвиг курсора с элемента", "loc.radio" : "Радиокнопка", - "loc.scrolling.center.js" : "Скроллинг в центр (при помощи JavaScript)", - "loc.scrolling.js" : "Скроллинг с помощью JavaScript", - "loc.selecting.value" : "Выбор значения", + "loc.scrolling.center.js" : "Скроллинг в центр (посредством JavaScript)", + "loc.scrolling.js" : "Скроллинг посредством JavaScript", + "loc.selecting.value" : "Выбор значения - '%s'", "loc.send.text" : "Ввод текста - '%s'", - "loc.setting.value" : "Установка значения '%s'", + "loc.setting.value" : "Установка значения - '%s'", "loc.text.clearing" : "Очистка", + "loc.text.submitting": "Отправка", "loc.text.field" : "Текстовое поле", - "loc.text.sending.keys" : "Нажатие клавиши '%s'", + "loc.text.sending.key" : "Нажатие клавиши '%s'", "loc.text.typing" : "Ввод текста '%s'", "loc.text.masked_value" : "********", - "loc.wait.timeout.condition": "Не удалось дождаться ожидаемого условия '%2$s' в течении %1$s секунд(ы)", - "loc.waitexists" : "Ожидаем появления элемента в DOM используя локатор: %1$s", - "loc.waitinstate" : "Ожидание присутствия элемента в состоянии %1$s используя локатор: %2$s", - "loc.waitinvisible" : "Ожидаем пока элемент исчезнет используя локатор: %1$s", - "loc.waitnotexists" : "Ожидаем исчезновения элемента из DOM используя локатор: %1$s", - "loc.no.elements.found.in.state" : "Не удалось найти элементов по локатору '%1$s' в состоянии '%2$s'", - "loc.no.elements.found.by.locator" : "Не удалось найти элементов по локатору '%1$s'", - "loc.elements.were.found.but.not.in.state" : "Удалось найти элементы по локатору '%1$s',но они не в желаемом состоянии. %2$s", - "loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s' в %2$s состоянии", - "loc.search.of.elements.failed": "Поиск элемента по локатору '%1$s' прошел неудачно", - "loc.element.not.in.state": "Элемент %1$s не стал %2$s после таймаута %3$s", - "loc.get.page.source.failed": "Произошла ошибка во время получения разметки страницы", "loc.browser.switch.to.tab.handle": "Переключение на новую вкладку по дескриптору '%1$s'", "loc.browser.switch.to.tab.index": "Переключение на новую вкладку по индексу '%1$s'", "loc.browser.switch.to.new.tab": "Переключение на новую вкладку", diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties index 0b181b8..7ce938d 100644 --- a/src/main/resources/log4j.properties +++ b/src/main/resources/log4j.properties @@ -1,4 +1,4 @@ -log4j.rootLogger=INFO, stdout, file +log4j.rootLogger=DEBUG, stdout, file log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.encoding=UTF-8 diff --git a/src/main/resources/settings.json b/src/main/resources/settings.json index fb56831..7b34b72 100644 --- a/src/main/resources/settings.json +++ b/src/main/resources/settings.json @@ -67,7 +67,8 @@ "pollingInterval": 300 }, "logger": { - "language": "en" + "language": "en", + "logPageSource": true }, "elementCache": { "isEnabled": false diff --git a/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java b/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java index 9dc73bd..e389b76 100644 --- a/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java +++ b/src/test/java/aquality/selenium/localization/LocalizationManagerTests.java @@ -1,6 +1,7 @@ package aquality.selenium.localization; import aquality.selenium.browser.AqualityServices; +import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.localization.ILocalizationManager; import aquality.selenium.core.localization.LocalizationManager; import aquality.selenium.core.logging.Logger; @@ -49,6 +50,16 @@ public void testShouldGetExceptionIfLocalizationFileIsNotExists() { } private LocalizationManager getLocalizationManager(String language) { - return new LocalizationManager(() -> language, Logger.getInstance()); + return new LocalizationManager(new ILoggerConfiguration() { + @Override + public String getLanguage() { + return language; + } + + @Override + public boolean logPageSource() { + return true; + } + }, Logger.getInstance()); } } \ No newline at end of file diff --git a/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java b/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java index f897410..9211993 100644 --- a/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java +++ b/src/test/java/aquality/selenium/utils/ElementActionRetrierTests.java @@ -51,7 +51,7 @@ public void testRetrierShouldWaitPollingTimeBetweenMethodsCall(RuntimeException throw handledException; } }); - DurationSample durationSample = new DurationSample( timer.duration(), pollingInterval, 200); + DurationSample durationSample = new DurationSample( timer.duration(), pollingInterval, 299); assertTrue(durationSample.isDurationBetweenLimits(), durationSample.toString()); } diff --git a/src/test/java/tests/integration/ElementStateTests.java b/src/test/java/tests/integration/ElementStateTests.java index c1eea4d..d5b9f88 100644 --- a/src/test/java/tests/integration/ElementStateTests.java +++ b/src/test/java/tests/integration/ElementStateTests.java @@ -18,8 +18,8 @@ public class ElementStateTests extends BaseTest { - private final Duration customWaitTime = Duration.ofSeconds(2L); - private final double customDeviation = 2; + private final Duration customWaitTime = Duration.ofSeconds(5L); + private final double customDeviation = 5; private final double defaultDeviation = 7; private final IElementFactory elementFactory = AqualityServices.get(IElementFactory.class); private final ILabel lblNotExists = elementFactory.getLabel(By.xpath("//div[@class='not exist element']"), "not exist element"); diff --git a/src/test/java/tests/integration/ElementTests.java b/src/test/java/tests/integration/ElementTests.java index 2e5bc4d..f9afade 100644 --- a/src/test/java/tests/integration/ElementTests.java +++ b/src/test/java/tests/integration/ElementTests.java @@ -103,6 +103,31 @@ public void testCheckBox() { Assert.assertEquals(checkBox2.isChecked(), stateSecond, ""); } + @Test + public void testCheckBoxJsActions() { + navigate(TheInternetPage.CHECKBOXES); + String checkboxLocator = "//input[@type='checkbox']"; + List checkBoxes = elementFactory.findElements(By.xpath(checkboxLocator), ICheckBox.class, + ElementsCount.MORE_THEN_ZERO, ElementState.DISPLAYED); + ICheckBox checkBox1 = checkBoxes.get(0); + ICheckBox checkBox2 = checkBoxes.get(1); + boolean stateFirst = checkBox1.getJsActions().isChecked(); + boolean stateSecond = checkBox2.getJsActions().isChecked(); + boolean state = checkBox1.getJsActions().isChecked(); + checkBox1.getJsActions().toggle(); + Assert.assertEquals(checkBox1.getJsActions().isChecked(), !state); + + checkBox2.getJsActions().uncheck(); + Assert.assertFalse(checkBox2.getJsActions().isChecked()); + + AqualityServices.getBrowser().refresh(); + checkBoxes = elementFactory.findElements(By.xpath(checkboxLocator), ElementType.CHECKBOX); + checkBox1 = checkBoxes.get(0); + checkBox2 = checkBoxes.get(1); + Assert.assertEquals(checkBox1.getJsActions().isChecked(), stateFirst, ""); + Assert.assertEquals(checkBox2.getJsActions().isChecked(), stateSecond, ""); + } + @Test public void testLink() { navigate(TheInternetPage.REDIRECTOR); diff --git a/src/test/java/tests/usecases/BrowserFactoryTests.java b/src/test/java/tests/usecases/BrowserFactoryTests.java index 9970997..48f544d 100644 --- a/src/test/java/tests/usecases/BrowserFactoryTests.java +++ b/src/test/java/tests/usecases/BrowserFactoryTests.java @@ -6,10 +6,15 @@ import aquality.selenium.browser.IBrowserFactory; import aquality.selenium.configuration.IBrowserProfile; import aquality.selenium.configuration.driversettings.FirefoxSettings; +import aquality.selenium.core.utilities.IActionRetrier; import aquality.selenium.core.utilities.ISettingsFile; import com.google.inject.Provider; import io.github.bonigarcia.wdm.WebDriverManager; +import org.openqa.selenium.SessionNotCreatedException; +import org.openqa.selenium.TimeoutException; +import org.openqa.selenium.WebDriverException; import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.remote.UnreachableBrowserException; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; @@ -22,6 +27,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; +import java.util.Arrays; import java.util.Comparator; import java.util.stream.Stream; @@ -46,7 +52,14 @@ private IBrowserFactory getCustomFactory() { return () -> { FirefoxSettings firefoxSettings = new FirefoxSettings(AqualityServices.get(ISettingsFile.class)); WebDriverManager.firefoxdriver().setup(); - FirefoxDriver driver = new FirefoxDriver(firefoxSettings.getCapabilities().setHeadless(true)); + FirefoxDriver driver = AqualityServices.get(IActionRetrier.class).doWithRetry( + () -> new FirefoxDriver(firefoxSettings.getCapabilities().setHeadless(true)), + Arrays.asList( + SessionNotCreatedException.class, + UnreachableBrowserException.class, + WebDriverException.class, + TimeoutException.class)); + return new Browser(driver); }; } diff --git a/src/test/java/tests/usecases/ShoppingCartTest.java b/src/test/java/tests/usecases/ShoppingCartTest.java index aa18b9c..ae05828 100644 --- a/src/test/java/tests/usecases/ShoppingCartTest.java +++ b/src/test/java/tests/usecases/ShoppingCartTest.java @@ -24,7 +24,7 @@ public void testShoppingCart() { SoftAssert softAssert = new SoftAssert(); SliderForm sliderForm = new SliderForm(); - Assert.assertTrue(sliderForm.isDisplayed()); + Assert.assertTrue(sliderForm.state().waitForDisplayed()); sliderForm.clickBtnNext(); sliderForm.clickBtnNext(); @@ -42,7 +42,7 @@ public void testShoppingCart() { softAssert.assertEquals(expectedQuantity, actualQuantity, "Quantity is not correct"); shoppingCardSummaryForm.clickProceedToCheckoutBtn(); - softAssert.assertTrue(new AuthenticationForm().isDisplayed()); + softAssert.assertTrue(new AuthenticationForm().state().waitForDisplayed()); CartMenuForm cartMenuForm = new CartMenuForm(); cartMenuForm.openCartMenu(); cartMenuForm.clickCheckoutBtn(); diff --git a/src/test/resources/settings.incorrect.json b/src/test/resources/settings.incorrect.json index 4e693b5..2a0e115 100644 --- a/src/test/resources/settings.incorrect.json +++ b/src/test/resources/settings.incorrect.json @@ -66,7 +66,8 @@ "pollingInterval": 300 }, "logger": { - "language": "en" + "language": "en", + "logPageSource": true }, "elementCache": { "isEnabled": false diff --git a/src/test/resources/settings.json b/src/test/resources/settings.json index 83d3a68..eee8a2f 100644 --- a/src/test/resources/settings.json +++ b/src/test/resources/settings.json @@ -66,7 +66,8 @@ "pollingInterval": 300 }, "logger": { - "language": "en" + "language": "en", + "logPageSource": true }, "elementCache": { "isEnabled": false diff --git a/src/test/resources/settings.local.json b/src/test/resources/settings.local.json index 7546dd5..a0bfaac 100644 --- a/src/test/resources/settings.local.json +++ b/src/test/resources/settings.local.json @@ -66,7 +66,8 @@ "pollingInterval": 300 }, "logger": { - "language": "en" + "language": "en", + "logPageSource": true }, "elementCache": { "isEnabled": false