From 061f16fe52bc06764b5d523df92aea2ab3b08492 Mon Sep 17 00:00:00 2001 From: Re-Kayle <52598902+1109471432@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:29:52 +0800 Subject: [PATCH 1/2] integrate selenoid (#3191) * feat: fix bug 3187 * feat: Integrate selenoid * feat: update serenity-selenoid version to 3.9.2-SNAPSHOT * feat: update serenity-selenoid remove Date API * Update serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/SerenitySelenoidUtil.java Co-authored-by: sonatype-lift[bot] <37194012+sonatype-lift[bot]@users.noreply.github.com> --------- Co-authored-by: kayle <1109481432@qq.com> Co-authored-by: sonatype-lift[bot] <37194012+sonatype-lift[bot]@users.noreply.github.com> --- pom.xml | 1 + serenity-selenoid/pom.xml | 68 +++++++++++++++++++ .../selenoid/AfterASelenoidScenario.java | 18 +++++ .../selenoid/BeforeASelenoidScenario.java | 50 ++++++++++++++ .../selenoid/SerenitySelenoidUtil.java | 57 ++++++++++++++++ .../WhenAddingSelenoidCapabilities.java | 49 +++++++++++++ 6 files changed, 243 insertions(+) create mode 100644 serenity-selenoid/pom.xml create mode 100644 serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/AfterASelenoidScenario.java create mode 100644 serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/BeforeASelenoidScenario.java create mode 100644 serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/SerenitySelenoidUtil.java create mode 100644 serenity-selenoid/src/test/java/net/serenitybdd/plugins/selenoid/WhenAddingSelenoidCapabilities.java diff --git a/pom.xml b/pom.xml index 190501355..6deff9cb2 100644 --- a/pom.xml +++ b/pom.xml @@ -761,6 +761,7 @@ serenity-cli serenity-screenplay-playwright serenity-bitbar + serenity-selenoid diff --git a/serenity-selenoid/pom.xml b/serenity-selenoid/pom.xml new file mode 100644 index 000000000..f04dd5287 --- /dev/null +++ b/serenity-selenoid/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + net.serenity-bdd + serenity-bdd + 3.9.2-SNAPSHOT + + + serenity-selenoid + jar + Serenity Screenplay selenoid Integration + + + + UTF-8 + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.serenitybdd.serenityselenoid + + + + + + + + + ${project.groupId} + serenity-core + ${project.version} + + + + junit + junit + test + + + ${project.groupId} + serenity-junit + ${project.version} + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.vintage + junit-vintage-engine + test + + + + \ No newline at end of file diff --git a/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/AfterASelenoidScenario.java b/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/AfterASelenoidScenario.java new file mode 100644 index 000000000..70520f530 --- /dev/null +++ b/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/AfterASelenoidScenario.java @@ -0,0 +1,18 @@ +package net.serenitybdd.plugins.selenoid; + +import net.serenitybdd.core.webdriver.RemoteDriver; +import net.serenitybdd.core.webdriver.enhancers.AfterAWebdriverScenario; +import net.thucydides.core.model.TestOutcome; +import net.thucydides.core.util.EnvironmentVariables; +import org.openqa.selenium.WebDriver; + +public class AfterASelenoidScenario implements AfterAWebdriverScenario { + + @Override + public void apply(EnvironmentVariables environmentVariables, TestOutcome testOutcome, WebDriver driver) { + if ((driver == null) || (!RemoteDriver.isARemoteDriver(driver))) { + return; + } + + } +} diff --git a/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/BeforeASelenoidScenario.java b/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/BeforeASelenoidScenario.java new file mode 100644 index 000000000..41d9e1dc1 --- /dev/null +++ b/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/BeforeASelenoidScenario.java @@ -0,0 +1,50 @@ +package net.serenitybdd.plugins.selenoid; + +import net.serenitybdd.core.webdriver.driverproviders.CapabilityValue; +import net.serenitybdd.core.webdriver.enhancers.BeforeAWebdriverScenario; +import net.thucydides.core.model.TestOutcome; +import net.thucydides.core.util.EnvironmentVariables; +import net.thucydides.core.webdriver.SupportedWebDriver; +import org.openqa.selenium.MutableCapabilities; +import org.openqa.selenium.remote.CapabilityType; +import org.openqa.selenium.remote.DesiredCapabilities; + +import java.util.*; + +import static net.serenitybdd.plugins.selenoid.SerenitySelenoidUtil.SELENOID; + +public class BeforeASelenoidScenario implements BeforeAWebdriverScenario { + + public static final List capability = Arrays.asList(CapabilityType.BROWSER_NAME, CapabilityType.BROWSER_VERSION, CapabilityType.PLATFORM_NAME); + + + @Override + public MutableCapabilities apply(EnvironmentVariables environmentVariables, SupportedWebDriver driver, TestOutcome testOutcome, MutableCapabilities capabilities) { + + if (driver != SupportedWebDriver.REMOTE) { + return capabilities; + } + Map SELENOID_PROPERTIES_MAP = new HashMap<>(); + String name = SerenitySelenoidUtil.getName(testOutcome); + SELENOID_PROPERTIES_MAP.put("name", name); + SELENOID_PROPERTIES_MAP.put("videoName", SerenitySelenoidUtil.getVideoName(name)); + + DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); + Properties selenoidProperties = environmentVariables.getPropertiesWithPrefix(SELENOID); + for (String propertyName : selenoidProperties.stringPropertyNames()) { + String unPrefixedPropertyName = SerenitySelenoidUtil.unprefixed(propertyName); + Object value = CapabilityValue.fromString(selenoidProperties.getProperty(propertyName)); + capability.stream().filter(k -> k.equalsIgnoreCase(unPrefixedPropertyName)).forEach(k -> desiredCapabilities.setCapability(k, value)); + SELENOID_PROPERTIES_MAP.put(unPrefixedPropertyName, value); + } + + SerenitySelenoidUtil.linkVideoToSerenityReport(testOutcome, SerenitySelenoidUtil.getVideoName(name)); + + + capabilities.setCapability("selenoid:options", SELENOID_PROPERTIES_MAP); + capabilities.merge(desiredCapabilities); + return capabilities; + } + + +} diff --git a/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/SerenitySelenoidUtil.java b/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/SerenitySelenoidUtil.java new file mode 100644 index 000000000..ac41cc9bc --- /dev/null +++ b/serenity-selenoid/src/main/java/net/serenitybdd/plugins/selenoid/SerenitySelenoidUtil.java @@ -0,0 +1,57 @@ +package net.serenitybdd.plugins.selenoid; + +import net.thucydides.core.environment.SystemEnvironmentVariables; +import net.thucydides.core.model.ExternalLink; +import net.thucydides.core.model.TestOutcome; +import net.thucydides.core.util.EnvironmentVariables; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.MalformedURLException; +import java.net.URL; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + + +public class SerenitySelenoidUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(SerenitySelenoidUtil.class); + + public static final String SELENOID = "selenoid."; + + public static EnvironmentVariables env = SystemEnvironmentVariables.currentEnvironmentVariables(); + + public static String getName(TestOutcome testOutcome) { + return String.format("%s-%s-%s", getVideoDataPrefix(), testOutcome.getStoryTitle(), testOutcome.getTitle()); + + } + + public static String getVideoName(String name) { + return String.format("%s%s", name, getVideoNameSuffix()); + } + + public static String getVideoDataPrefix() { + String dataFormat = env.getProperty(SELENOID + "videoDataPrefixFormat", "yyyy-MM-dd"); + return DateTimeFormatter.ofPattern(dataFormat).format(LocalDateTime.now(ZoneId.systemDefault())); + } + + public static String getVideoNameSuffix() { + return env.getProperty(SELENOID + "videoSuffix", ".mp4"); + } + + protected static void linkVideoToSerenityReport(TestOutcome testOutcome, String link) { + try { + URL url = new URL(env.getProperty("webdriver.remote.url")); + String videoLinkPrefix = env.getProperty(SELENOID + "videoLinkPrefix", String.format("%s:%s:8080/video", url.getProtocol(), url.getHost())); + testOutcome.setLink(new ExternalLink(String.format("%s/%s", videoLinkPrefix, link), "BrowserStack")); + } catch (MalformedURLException e) { + LOGGER.error("Set video link error. {}", e.getMessage()); + } + + } + + protected static String unprefixed(String propertyName) { + return propertyName.replace(SELENOID, ""); + } + +} diff --git a/serenity-selenoid/src/test/java/net/serenitybdd/plugins/selenoid/WhenAddingSelenoidCapabilities.java b/serenity-selenoid/src/test/java/net/serenitybdd/plugins/selenoid/WhenAddingSelenoidCapabilities.java new file mode 100644 index 000000000..298240fdb --- /dev/null +++ b/serenity-selenoid/src/test/java/net/serenitybdd/plugins/selenoid/WhenAddingSelenoidCapabilities.java @@ -0,0 +1,49 @@ +package net.serenitybdd.plugins.selenoid; + +import net.serenitybdd.core.webdriver.driverproviders.AddCustomDriverCapabilities; +import net.thucydides.core.environment.MockEnvironmentVariables; +import net.thucydides.core.model.Story; +import net.thucydides.core.model.TestOutcome; +import net.thucydides.core.util.EnvironmentVariables; +import net.thucydides.core.webdriver.SupportedWebDriver; +import org.junit.Test; +import org.openqa.selenium.remote.DesiredCapabilities; + +import java.util.HashMap; + +import static org.assertj.core.api.Assertions.assertThat; + +public class WhenAddingSelenoidCapabilities { + + EnvironmentVariables environmentVariables = new MockEnvironmentVariables(); + + @Test + public void shouldAddTheNameOfTheTest() { + + // Given + DesiredCapabilities capabilities = new DesiredCapabilities(); + TestOutcome testOutcome = TestOutcome.forTestInStory("serenity_selenoid_test", Story.called("Sample story")); + String name = SerenitySelenoidUtil.getName(testOutcome); + + AddCustomDriverCapabilities.from(environmentVariables) + .withTestDetails(SupportedWebDriver.REMOTE, testOutcome) + .to(capabilities); + Object capability = capabilities.getCapability("selenoid:options"); + assertThat(((HashMap) capability).get("name")).isEqualTo(name); + } + + @Test + public void shouldAddZaleniumPropertiesFromTheEnvironmentConfiguration() { + + // Given + DesiredCapabilities capabilities = new DesiredCapabilities(); + TestOutcome testOutcome = TestOutcome.forTestInStory("serenity_selenoid_test", Story.called("Sample story")); + environmentVariables.setProperty("selenoid.enableVNC", "true"); + + AddCustomDriverCapabilities.from(environmentVariables).withTestDetails(SupportedWebDriver.REMOTE, testOutcome).to(capabilities); + Object capability = capabilities.getCapability("selenoid:options"); + assertThat(((HashMap) capability).get("enableVNC")).isEqualTo(true); + + } + +} From a46a7df058972dc916326f7b4dd6f32e84cc6c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Becker?= Date: Mon, 17 Jul 2023 10:30:55 +0200 Subject: [PATCH 2/2] enable list matcher to be used with Check class (#3182) --- .../main/java/net/serenitybdd/screenplay/conditions/Check.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serenity-screenplay/src/main/java/net/serenitybdd/screenplay/conditions/Check.java b/serenity-screenplay/src/main/java/net/serenitybdd/screenplay/conditions/Check.java index 87c993d07..30135c183 100644 --- a/serenity-screenplay/src/main/java/net/serenitybdd/screenplay/conditions/Check.java +++ b/serenity-screenplay/src/main/java/net/serenitybdd/screenplay/conditions/Check.java @@ -12,7 +12,7 @@ public static ConditionalPerformable whether(Question condition) { return new ConditionalPerformableOnQuestion(condition); } - public static ConditionalPerformable whether(Question question, Matcher matcher) { + public static ConditionalPerformable whether(Question question, Matcher matcher) { Question condition = actor -> matcher.matches(question.answeredBy(actor)); return new ConditionalPerformableOnQuestion(condition);