diff --git a/docs/modules/plugins/partials/dynamic-variables-ui.adoc b/docs/modules/plugins/partials/dynamic-variables-ui.adoc index 44275c30c4..c0e85bcce0 100644 --- a/docs/modules/plugins/partials/dynamic-variables-ui.adoc +++ b/docs/modules/plugins/partials/dynamic-variables-ui.adoc @@ -42,11 +42,33 @@ Then `${context-x-coordinate}` is > `0` Then `${context-y-coordinate}` is > `0` ---- +=== Context source code + +Variable provides source code of the current UI context of the application under test. + +[source,gherkin] +---- +${context-source-code} +---- + +.Firstly check frames on the entire page, and then links in the specified context +[source,gherkin] +---- +Given I am on main application page +Then all resources by selector `frame,iframe` from ${context-source-code} are valid +When I change context to element located by `id(linksList)` +Then all resources by selector `a` from ${context-source-code} are valid +---- === Source code Variable provides source code of the UI of the application under test. +[WARNING] +==== +The variable is deprecated and will be removed in VIVIDUS 0.7.0. Please use `${context-source-code}` dynamic variable instead. +==== + ==== *Variable name* [source,gherkin] diff --git a/vividus-extension-selenium/src/main/java/org/vividus/ui/ContextSourceCodeProvider.java b/vividus-extension-selenium/src/main/java/org/vividus/ui/ContextSourceCodeProvider.java new file mode 100644 index 0000000000..a5a10b2d43 --- /dev/null +++ b/vividus-extension-selenium/src/main/java/org/vividus/ui/ContextSourceCodeProvider.java @@ -0,0 +1,26 @@ +/* + * Copyright 2019-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.ui; + +import java.util.Map; + +public interface ContextSourceCodeProvider +{ + String APPLICATION_SOURCE_CODE = "Application source code"; + + Map getSourceCode(); +} diff --git a/vividus-extension-selenium/src/main/java/org/vividus/ui/listener/AbstractSourceCodePublishingOnFailureListener.java b/vividus-extension-selenium/src/main/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListener.java similarity index 72% rename from vividus-extension-selenium/src/main/java/org/vividus/ui/listener/AbstractSourceCodePublishingOnFailureListener.java rename to vividus-extension-selenium/src/main/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListener.java index 734a51d339..d78b1e543d 100644 --- a/vividus-extension-selenium/src/main/java/org/vividus/ui/listener/AbstractSourceCodePublishingOnFailureListener.java +++ b/vividus-extension-selenium/src/main/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,23 +23,23 @@ import org.vividus.reporter.event.IAttachmentPublisher; import org.vividus.selenium.IWebDriverProvider; import org.vividus.softassert.event.AssertionFailedEvent; +import org.vividus.ui.ContextSourceCodeProvider; -public abstract class AbstractSourceCodePublishingOnFailureListener +public class SourceCodePublishingOnFailureListener { - protected static final String APPLICATION_SOURCE_CODE = "Application source code"; - - private final IAttachmentPublisher attachmentPublisher; private final IWebDriverProvider webDriverProvider; - private final String format; + private final ContextSourceCodeProvider contextSourceCodeProvider; + private final IAttachmentPublisher attachmentPublisher; private boolean publishSourceOnFailure; + private String format; - protected AbstractSourceCodePublishingOnFailureListener(IAttachmentPublisher attachmentPublisher, - IWebDriverProvider webDriverProvider, String format) + public SourceCodePublishingOnFailureListener(IWebDriverProvider webDriverProvider, + ContextSourceCodeProvider contextSourceCodeProvider, IAttachmentPublisher attachmentPublisher) { this.webDriverProvider = webDriverProvider; + this.contextSourceCodeProvider = contextSourceCodeProvider; this.attachmentPublisher = attachmentPublisher; - this.format = format; } @Subscribe @@ -47,7 +47,7 @@ public void onAssertionFailure(AssertionFailedEvent event) { if (publishSourceOnFailure && webDriverProvider.isWebDriverInitialized()) { - getSourceCode().forEach(this::publishSource); + contextSourceCodeProvider.getSourceCode().forEach(this::publishSource); } } @@ -57,15 +57,13 @@ private void publishSource(String title, String source) Map.of("sourceCode", source, "format", format), title); } - protected abstract Map getSourceCode(); - public void setPublishSourceOnFailure(boolean publishSourceOnFailure) { this.publishSourceOnFailure = publishSourceOnFailure; } - protected IWebDriverProvider getWebDriverProvider() + public void setFormat(String format) { - return webDriverProvider; + this.format = format; } } diff --git a/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/ContextSourceCodeDynamicVariable.java b/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/ContextSourceCodeDynamicVariable.java new file mode 100644 index 0000000000..9b7e0b8b8f --- /dev/null +++ b/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/ContextSourceCodeDynamicVariable.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.ui.variable; + +import static org.vividus.ui.ContextSourceCodeProvider.APPLICATION_SOURCE_CODE; + +import org.vividus.ui.ContextSourceCodeProvider; +import org.vividus.variable.DynamicVariable; +import org.vividus.variable.DynamicVariableCalculationResult; + +public class ContextSourceCodeDynamicVariable implements DynamicVariable +{ + private final ContextSourceCodeProvider contextSourceCodeProvider; + + public ContextSourceCodeDynamicVariable(ContextSourceCodeProvider contextSourceCodeProvider) + { + this.contextSourceCodeProvider = contextSourceCodeProvider; + } + + @Override + public DynamicVariableCalculationResult calculateValue() + { + String contextSourceCode = contextSourceCodeProvider.getSourceCode().get(APPLICATION_SOURCE_CODE); + return contextSourceCode != null + ? DynamicVariableCalculationResult.withValue(contextSourceCode) + : DynamicVariableCalculationResult.withError("application is not started"); + } +} diff --git a/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/SourceCodeDynamicVariable.java b/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/SourceCodeDynamicVariable.java index f7caec3fd5..0b0d359ab6 100644 --- a/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/SourceCodeDynamicVariable.java +++ b/vividus-extension-selenium/src/main/java/org/vividus/ui/variable/SourceCodeDynamicVariable.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,25 @@ package org.vividus.ui.variable; import org.openqa.selenium.WebDriver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.vividus.selenium.IWebDriverProvider; +import org.vividus.variable.DynamicVariableCalculationResult; public class SourceCodeDynamicVariable extends AbstractWebDriverDynamicVariable { + private static final Logger LOGGER = LoggerFactory.getLogger(SourceCodeDynamicVariable.class); + public SourceCodeDynamicVariable(IWebDriverProvider webDriverProvider) { super(webDriverProvider, WebDriver::getPageSource); } + + @Override + public DynamicVariableCalculationResult calculateValue() + { + LOGGER.warn("The \"${source-code}\" dynamic variable is deprecated and will be removed in VIVIDUS 0.7.0. " + + "Please use \"${context-source-code}\" dynamic variable instead."); + return super.calculateValue(); + } } diff --git a/vividus-extension-selenium/src/main/resources/vividus-extension/spring.xml b/vividus-extension-selenium/src/main/resources/vividus-extension/spring.xml index fb6303193d..6571e031aa 100644 --- a/vividus-extension-selenium/src/main/resources/vividus-extension/spring.xml +++ b/vividus-extension-selenium/src/main/resources/vividus-extension/spring.xml @@ -130,11 +130,6 @@ - - - - @@ -221,6 +216,7 @@ + diff --git a/vividus-extension-selenium/src/test/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListenerTests.java b/vividus-extension-selenium/src/test/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListenerTests.java index 6003bf7d7b..ef8dd97361 100644 --- a/vividus-extension-selenium/src/test/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListenerTests.java +++ b/vividus-extension-selenium/src/test/java/org/vividus/ui/listener/SourceCodePublishingOnFailureListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import static org.vividus.ui.ContextSourceCodeProvider.APPLICATION_SOURCE_CODE; import java.util.Map; @@ -30,6 +31,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.vividus.reporter.event.IAttachmentPublisher; import org.vividus.selenium.IWebDriverProvider; +import org.vividus.ui.ContextSourceCodeProvider; @ExtendWith(MockitoExtension.class) class SourceCodePublishingOnFailureListenerTests @@ -37,13 +39,11 @@ class SourceCodePublishingOnFailureListenerTests private static final String SOURCES = ""; private static final String HTML = "HTML"; - @Mock - private IAttachmentPublisher attachmentPublisher; - @Mock - private IWebDriverProvider webDriverProvider; + @Mock private IWebDriverProvider webDriverProvider; + @Mock private ContextSourceCodeProvider contextSourceCodeProvider; + @Mock private IAttachmentPublisher attachmentPublisher; - @InjectMocks - private TestSorceCodePublishingOnFailureListener listener; + @InjectMocks private SourceCodePublishingOnFailureListener listener; @Test void shouldNoPublishSourceCodeWhenPublishingDisabled() @@ -67,55 +67,25 @@ void shouldNoPublishSourceCodeWhenWebDriverIsNotInitialized() void shouldPublishSourceCode() { when(webDriverProvider.isWebDriverInitialized()).thenReturn(true); + when(contextSourceCodeProvider.getSourceCode()).thenReturn(Map.of(APPLICATION_SOURCE_CODE, SOURCES)); + listener.setFormat(HTML); listener.setPublishSourceOnFailure(true); listener.onAssertionFailure(null); verify(webDriverProvider).isWebDriverInitialized(); verify(attachmentPublisher).publishAttachment("/templates/source-code.ftl", Map.of("sourceCode", SOURCES, "format", HTML), "Application source code"); - verifyNoMoreInteractions(webDriverProvider, attachmentPublisher); + verifyNoMoreInteractions(webDriverProvider, contextSourceCodeProvider, attachmentPublisher); } @Test void shouldNotPublishMissingSource() { - TestEmptySorceCodePublishingOnFailureListener listener = new TestEmptySorceCodePublishingOnFailureListener( - attachmentPublisher, webDriverProvider); when(webDriverProvider.isWebDriverInitialized()).thenReturn(true); + when(contextSourceCodeProvider.getSourceCode()).thenReturn(Map.of()); listener.setPublishSourceOnFailure(true); listener.onAssertionFailure(null); verify(webDriverProvider).isWebDriverInitialized(); verifyNoInteractions(attachmentPublisher); - verifyNoMoreInteractions(webDriverProvider, attachmentPublisher); - } - - private static class TestSorceCodePublishingOnFailureListener extends AbstractSourceCodePublishingOnFailureListener - { - protected TestSorceCodePublishingOnFailureListener(IAttachmentPublisher attachmentPublisher, - IWebDriverProvider webDriverProvider) - { - super(attachmentPublisher, webDriverProvider, HTML); - } - - @Override - protected Map getSourceCode() - { - return Map.of(APPLICATION_SOURCE_CODE, SOURCES); - } - } - - private static final class TestEmptySorceCodePublishingOnFailureListener - extends TestSorceCodePublishingOnFailureListener - { - protected TestEmptySorceCodePublishingOnFailureListener(IAttachmentPublisher attachmentPublisher, - IWebDriverProvider webDriverProvider) - { - super(attachmentPublisher, webDriverProvider); - } - - @Override - protected Map getSourceCode() - { - return Map.of(); - } + verifyNoMoreInteractions(webDriverProvider, contextSourceCodeProvider); } } diff --git a/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/ContextSourceCodeDynamicVariableTests.java b/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/ContextSourceCodeDynamicVariableTests.java new file mode 100644 index 0000000000..93ebac5d6d --- /dev/null +++ b/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/ContextSourceCodeDynamicVariableTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.ui.variable; + +import static com.github.valfirst.slf4jtest.LoggingEvent.error; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; +import static org.vividus.ui.ContextSourceCodeProvider.APPLICATION_SOURCE_CODE; + +import java.util.List; +import java.util.Map; + +import com.github.valfirst.slf4jtest.TestLogger; +import com.github.valfirst.slf4jtest.TestLoggerFactory; +import com.github.valfirst.slf4jtest.TestLoggerFactoryExtension; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.vividus.ui.ContextSourceCodeProvider; +import org.vividus.variable.DynamicVariableCalculationResult; + +@ExtendWith({ TestLoggerFactoryExtension.class, MockitoExtension.class }) +class ContextSourceCodeDynamicVariableTests +{ + private static final String SOURCES = ""; + + private final TestLogger logger = TestLoggerFactory.getTestLogger(ContextSourceCodeDynamicVariable.class); + + @Mock private ContextSourceCodeProvider contextSourceCodeProvider; + @InjectMocks private ContextSourceCodeDynamicVariable dynamicVariable; + + @Test + void shouldReturnSourceCodeAsResultIfApplicationStarted() + { + when(contextSourceCodeProvider.getSourceCode()).thenReturn(Map.of(APPLICATION_SOURCE_CODE, SOURCES)); + DynamicVariableCalculationResult actualResult = dynamicVariable.calculateValue(); + assertEquals(SOURCES, actualResult.getValueOrHandleError(null).get()); + } + + @Test + void shouldReturnErrorAsResultIfApplicationNotStarted() + { + when(contextSourceCodeProvider.getSourceCode()).thenReturn(Map.of()); + DynamicVariableCalculationResult actualResult = dynamicVariable.calculateValue(); + actualResult.getValueOrHandleError(logger::error); + assertEquals(List.of(error("application is not started")), logger.getLoggingEvents()); + } +} diff --git a/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/SourceCodeDynamicVariableTests.java b/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/SourceCodeDynamicVariableTests.java index f74e7b5bf8..2ce273ee00 100644 --- a/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/SourceCodeDynamicVariableTests.java +++ b/vividus-extension-selenium/src/test/java/org/vividus/ui/variable/SourceCodeDynamicVariableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,17 @@ package org.vividus.ui.variable; +import static com.github.valfirst.slf4jtest.LoggingEvent.warn; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.List; + +import com.github.valfirst.slf4jtest.TestLogger; +import com.github.valfirst.slf4jtest.TestLoggerFactory; +import com.github.valfirst.slf4jtest.TestLoggerFactoryExtension; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -29,9 +36,11 @@ import org.vividus.selenium.IWebDriverProvider; import org.vividus.variable.DynamicVariableCalculationResult; -@ExtendWith(MockitoExtension.class) +@ExtendWith({ TestLoggerFactoryExtension.class, MockitoExtension.class }) class SourceCodeDynamicVariableTests { + private final TestLogger logger = TestLoggerFactory.getTestLogger(SourceCodeDynamicVariable.class); + @Mock private IWebDriverProvider webDriverProvider; @InjectMocks private SourceCodeDynamicVariable dynamicVariable; @@ -45,6 +54,9 @@ void shouldReturnPageSource() when(driver.getPageSource()).thenReturn(sources); assertEquals(DynamicVariableCalculationResult.withValue(sources), dynamicVariable.calculateValue()); + assertEquals(List.of(warn( + "The \"${source-code}\" dynamic variable is deprecated and will be removed in VIVIDUS 0.7.0. " + + "Please use \"${context-source-code}\" dynamic variable instead.")), logger.getLoggingEvents()); } @Test diff --git a/vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/listener/MobileSourceCodePublishingOnFailureListener.java b/vividus-plugin-mobile-app/src/main/java/org/vividus/selenium/mobileapp/MobileContextSourceCodeProvider.java similarity index 54% rename from vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/listener/MobileSourceCodePublishingOnFailureListener.java rename to vividus-plugin-mobile-app/src/main/java/org/vividus/selenium/mobileapp/MobileContextSourceCodeProvider.java index 69d52a9008..6ae02849e0 100644 --- a/vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/listener/MobileSourceCodePublishingOnFailureListener.java +++ b/vividus-plugin-mobile-app/src/main/java/org/vividus/selenium/mobileapp/MobileContextSourceCodeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,27 +14,27 @@ * limitations under the License. */ -package org.vividus.mobileapp.listener; +package org.vividus.selenium.mobileapp; import java.util.Map; import java.util.Optional; -import org.vividus.reporter.event.IAttachmentPublisher; import org.vividus.selenium.IWebDriverProvider; -import org.vividus.ui.listener.AbstractSourceCodePublishingOnFailureListener; +import org.vividus.ui.ContextSourceCodeProvider; -public class MobileSourceCodePublishingOnFailureListener extends AbstractSourceCodePublishingOnFailureListener +public class MobileContextSourceCodeProvider implements ContextSourceCodeProvider { - public MobileSourceCodePublishingOnFailureListener(IAttachmentPublisher attachmentPublisher, - IWebDriverProvider webDriverProvider) + private final IWebDriverProvider webDriverProvider; + + public MobileContextSourceCodeProvider(IWebDriverProvider webDriverProvider) { - super(attachmentPublisher, webDriverProvider, "XML"); + this.webDriverProvider = webDriverProvider; } @Override - protected Map getSourceCode() + public Map getSourceCode() { - return Optional.ofNullable(getWebDriverProvider().get().getPageSource()) + return Optional.ofNullable(webDriverProvider.get().getPageSource()) .map(sc -> Map.of(APPLICATION_SOURCE_CODE, sc)) .orElseGet(Map::of); } diff --git a/vividus-plugin-mobile-app/src/main/resources/vividus-plugin/spring.xml b/vividus-plugin-mobile-app/src/main/resources/vividus-plugin/spring.xml index 28a8e46e4b..38a3f24a62 100644 --- a/vividus-plugin-mobile-app/src/main/resources/vividus-plugin/spring.xml +++ b/vividus-plugin-mobile-app/src/main/resources/vividus-plugin/spring.xml @@ -25,7 +25,12 @@ - + + + + + + diff --git a/vividus-plugin-mobile-app/src/test/java/org/vividus/mobileapp/listener/MobileSourceCodePublishingOnFailureListenerTests.java b/vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/MobileContextSourceCodeProviderTests.java similarity index 84% rename from vividus-plugin-mobile-app/src/test/java/org/vividus/mobileapp/listener/MobileSourceCodePublishingOnFailureListenerTests.java rename to vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/MobileContextSourceCodeProviderTests.java index 4544e715fc..53b21e454b 100644 --- a/vividus-plugin-mobile-app/src/test/java/org/vividus/mobileapp/listener/MobileSourceCodePublishingOnFailureListenerTests.java +++ b/vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/MobileContextSourceCodeProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.vividus.mobileapp.listener; +package org.vividus.selenium.mobileapp; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @@ -31,10 +31,10 @@ import org.vividus.selenium.IWebDriverProvider; @ExtendWith(MockitoExtension.class) -class MobileSourceCodePublishingOnFailureListenerTests +class MobileContextSourceCodeProviderTests { @Mock private IWebDriverProvider webDriverProvider; - @InjectMocks private MobileSourceCodePublishingOnFailureListener listener; + @InjectMocks private MobileContextSourceCodeProvider sourceCodeProvider; @Test void shouldReturnSourceCode() @@ -43,6 +43,6 @@ void shouldReturnSourceCode() String source = ""; when(webDriver.getPageSource()).thenReturn(source); when(webDriverProvider.get()).thenReturn(webDriver); - assertEquals(Map.of("Application source code", source), listener.getSourceCode()); + assertEquals(Map.of("Application source code", source), sourceCodeProvider.getSourceCode()); } } diff --git a/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/listener/WebSourceCodePublishingOnFailureListener.java b/vividus-plugin-web-app/src/main/java/org/vividus/selenium/WebContextSourceCodeProvider.java similarity index 82% rename from vividus-plugin-web-app/src/main/java/org/vividus/ui/web/listener/WebSourceCodePublishingOnFailureListener.java rename to vividus-plugin-web-app/src/main/java/org/vividus/selenium/WebContextSourceCodeProvider.java index 97de729204..82b3c76d5b 100644 --- a/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/listener/WebSourceCodePublishingOnFailureListener.java +++ b/vividus-plugin-web-app/src/main/java/org/vividus/selenium/WebContextSourceCodeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.vividus.ui.web.listener; +package org.vividus.selenium; import java.util.LinkedHashMap; import java.util.Map; @@ -25,30 +25,26 @@ import org.openqa.selenium.WebElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.vividus.reporter.event.IAttachmentPublisher; -import org.vividus.selenium.IWebDriverProvider; +import org.vividus.ui.ContextSourceCodeProvider; import org.vividus.ui.context.IUiContext; -import org.vividus.ui.listener.AbstractSourceCodePublishingOnFailureListener; import org.vividus.ui.web.action.CssSelectorFactory; import org.vividus.ui.web.action.WebJavascriptActions; -public class WebSourceCodePublishingOnFailureListener extends AbstractSourceCodePublishingOnFailureListener +public class WebContextSourceCodeProvider implements ContextSourceCodeProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(WebSourceCodePublishingOnFailureListener.class); + private static final Logger LOGGER = LoggerFactory.getLogger(WebContextSourceCodeProvider.class); private final IUiContext uiContext; private final WebJavascriptActions webJavascriptActions; - protected WebSourceCodePublishingOnFailureListener(IAttachmentPublisher attachmentPublisher, IWebDriverProvider - webDriverProvider, IUiContext uiContext, WebJavascriptActions webJavascriptActions) + protected WebContextSourceCodeProvider(IUiContext uiContext, WebJavascriptActions webJavascriptActions) { - super(attachmentPublisher, webDriverProvider, "HTML"); this.uiContext = uiContext; this.webJavascriptActions = webJavascriptActions; } @Override - protected Map getSourceCode() + public Map getSourceCode() { SearchContext searchContext = uiContext.getSearchContext(); String sourceCode = null; diff --git a/vividus-plugin-web-app/src/main/resources/vividus-plugin/spring.xml b/vividus-plugin-web-app/src/main/resources/vividus-plugin/spring.xml index b3dffe159b..643a48bd49 100644 --- a/vividus-plugin-web-app/src/main/resources/vividus-plugin/spring.xml +++ b/vividus-plugin-web-app/src/main/resources/vividus-plugin/spring.xml @@ -225,7 +225,12 @@ - + + + + + + diff --git a/vividus-plugin-web-app/src/test/java/org/vividus/ui/web/listener/WebSourceCodePublishingOnFailureListenerTests.java b/vividus-plugin-web-app/src/test/java/org/vividus/selenium/WebContextSourceCodeProviderTests.java similarity index 90% rename from vividus-plugin-web-app/src/test/java/org/vividus/ui/web/listener/WebSourceCodePublishingOnFailureListenerTests.java rename to vividus-plugin-web-app/src/test/java/org/vividus/selenium/WebContextSourceCodeProviderTests.java index 75b412fbea..ca202137fd 100644 --- a/vividus-plugin-web-app/src/test/java/org/vividus/ui/web/listener/WebSourceCodePublishingOnFailureListenerTests.java +++ b/vividus-plugin-web-app/src/test/java/org/vividus/selenium/WebContextSourceCodeProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * Copyright 2019-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.vividus.ui.web.listener; +package org.vividus.selenium; import static com.github.valfirst.slf4jtest.LoggingEvent.debug; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -42,7 +42,7 @@ import org.vividus.ui.web.action.WebJavascriptActions; @ExtendWith({ MockitoExtension.class, TestLoggerFactoryExtension.class}) -class WebSourceCodePublishingOnFailureListenerTests +class WebContextSourceCodeProviderTests { private static final String OUTER_HTML_SCRIPT = "return arguments[0].outerHTML;"; private static final String SHADOW_DOM_SCRIPT = CssSelectorFactory.CSS_SELECTOR_FACTORY_SCRIPT @@ -64,9 +64,9 @@ class WebSourceCodePublishingOnFailureListenerTests @Mock private IUiContext uiContext; @Mock private WebJavascriptActions webJavascriptActions; - @InjectMocks private WebSourceCodePublishingOnFailureListener listener; + @InjectMocks private WebContextSourceCodeProvider sourceCodeProvider; - private final TestLogger logger = TestLoggerFactory.getTestLogger(WebSourceCodePublishingOnFailureListener.class); + private final TestLogger logger = TestLoggerFactory.getTestLogger(WebContextSourceCodeProvider.class); @Test void shouldReturnWholePageForDriverContext() @@ -79,7 +79,8 @@ void shouldReturnWholePageForDriverContext() when(webJavascriptActions.executeScript( String.format(SHADOW_DOM_SCRIPT, "document.documentElement"))).thenReturn( Map.of(sourceTitle, pageSource)); - assertEquals(Map.of(APPLICATION_SOURCE_CODE, pageSource, sourceTitle, pageSource), listener.getSourceCode()); + assertEquals(Map.of(APPLICATION_SOURCE_CODE, pageSource, sourceTitle, pageSource), + sourceCodeProvider.getSourceCode()); } @Test @@ -92,7 +93,7 @@ void shouldReturnElementSourceForElementContext() mockShadowDomSourcesRetrieval(webElement, Map.of(sourceTitle, elementSource)); when(webJavascriptActions.executeScript(OUTER_HTML_SCRIPT, webElement)).thenReturn(elementSource); assertEquals(Map.of(APPLICATION_SOURCE_CODE, elementSource, sourceTitle, elementSource), - listener.getSourceCode()); + sourceCodeProvider.getSourceCode()); } @Test @@ -103,7 +104,7 @@ void shouldHandleStaleElementsCorrectly() when(webJavascriptActions.executeScript(OUTER_HTML_SCRIPT, webElement)).thenThrow( StaleElementReferenceException.class); mockShadowDomSourcesRetrieval(webElement, Map.of()); - assertEquals(Map.of(), listener.getSourceCode()); + assertEquals(Map.of(), sourceCodeProvider.getSourceCode()); assertEquals(logger.getLoggingEvents(), List.of(debug("Unable to get sources of the stale element"))); } @@ -112,7 +113,7 @@ void shouldReturnEmptyValueForNullSearchContext() { when(uiContext.getSearchContext()).thenReturn(null); when(webJavascriptActions.executeScript(any(String.class))).thenReturn(Map.of()); - assertEquals(Map.of(), listener.getSourceCode()); + assertEquals(Map.of(), sourceCodeProvider.getSourceCode()); } private void mockShadowDomSourcesRetrieval(WebElement webElement, Map sources) diff --git a/vividus-tests/src/main/resources/story/integration/DynamicVariablesTests.story b/vividus-tests/src/main/resources/story/integration/DynamicVariablesTests.story index 81925011d8..63e4250307 100644 --- a/vividus-tests/src/main/resources/story/integration/DynamicVariablesTests.story +++ b/vividus-tests/src/main/resources/story/integration/DynamicVariablesTests.story @@ -34,3 +34,9 @@ Scenario: Verify browser windows size dynamic variables When I change window size to `600x500` Then `${browser-window-height}` is = `500` Then `${browser-window-width}` is = `600` + +Scenario: Verify `context-source-code` dynamic variable +When I reset context +Then `${context-source-code}` matches `^.+` +When I change context to element located by `elementName(vividus-logo)` +Then `${context-source-code}` matches `^` Then all resources found by xpath `//a` in ${${source-code}} are valid !-- Deprecated Then all resources by selector `a` from ${source-code} are valid +When I change context to element located by `linkText(Link to unexistent element)` +Then all resources by selector `a` from ${context-source-code} are valid diff --git a/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story b/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story index 1c69f8abcf..ebf285720f 100644 --- a/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story +++ b/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story @@ -27,8 +27,9 @@ When I reinstall mobile application with bundle identifier `${main-app}` When I wait until element located by `xpath()->filter.text(Home)` appears -Scenario: Validate coordinate/size dynamic variables, page source dynamic variable +Scenario: Validate coordinate/size dynamic variables, page source dynamic variables Then `${source-code}` matches `.+Home.+` +Then `${context-source-code}` matches `.+Home.+` When I change context to element located by `xpath()->filter.text(Home)` Then `${context-height}` is > `0` Then `${context-width}` is > `0`