failures = new LinkedList<>();
public NeodymiumCucumberRunListener()
{
- SelenideLogger.addListener("allure-selenide", new AllureSelenide());
+ SelenideLogger.addListener(LISTENER_NAME, new AllureSelenide());
}
@Override
diff --git a/src/main/java/com/xceptance/neodymium/NeodymiumRunner.java b/src/main/java/com/xceptance/neodymium/NeodymiumRunner.java
index 2afeae2fb..4bb74f4f6 100644
--- a/src/main/java/com/xceptance/neodymium/NeodymiumRunner.java
+++ b/src/main/java/com/xceptance/neodymium/NeodymiumRunner.java
@@ -17,12 +17,15 @@
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
+import com.codeborne.selenide.logevents.SelenideLogger;
import com.xceptance.neodymium.module.EnhancedMethod;
import com.xceptance.neodymium.module.StatementBuilder;
import com.xceptance.neodymium.module.order.DefaultStatementRunOrder;
import com.xceptance.neodymium.module.statement.browser.multibrowser.Browser;
import com.xceptance.neodymium.util.Neodymium;
+import io.qameta.allure.selenide.AllureSelenide;
+
/**
* This class executes {@link JUnit4} test classes (aka JUnit Runner) and adds several features to test execution e.g.
* multi {@link Browser browser} and
@@ -66,9 +69,12 @@
*/
public class NeodymiumRunner extends BlockJUnit4ClassRunner
{
+ public static final String LISTENER_NAME = "allure-selenide-java";
+
public NeodymiumRunner(Class> klass) throws InitializationError
{
super(klass);
+ SelenideLogger.addListener(LISTENER_NAME, new AllureSelenide());
}
public enum DescriptionMode
diff --git a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/configuration/BrowserConfigurationMapper.java b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/configuration/BrowserConfigurationMapper.java
index 4e296d2a9..c669543d5 100644
--- a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/configuration/BrowserConfigurationMapper.java
+++ b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/configuration/BrowserConfigurationMapper.java
@@ -102,7 +102,7 @@ else if ("opera".equals(emulatedBrowser))
}
else
{
- capabilities = DesiredCapabilities.firefox();
+ capabilities = new DesiredCapabilities();
}
/*
diff --git a/src/main/java/com/xceptance/neodymium/util/SelenideAddons.java b/src/main/java/com/xceptance/neodymium/util/SelenideAddons.java
index 3b2753ea0..f20bc0abd 100644
--- a/src/main/java/com/xceptance/neodymium/util/SelenideAddons.java
+++ b/src/main/java/com/xceptance/neodymium/util/SelenideAddons.java
@@ -8,9 +8,13 @@
import org.openqa.selenium.By;
import org.openqa.selenium.StaleElementReferenceException;
+import org.openqa.selenium.WebElement;
+import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement;
+import com.codeborne.selenide.ex.UIAssertionError;
+import com.codeborne.selenide.impl.Html;
import com.codeborne.selenide.impl.WebElementsCollectionWrapper;
/**
@@ -143,4 +147,75 @@ public ElementsCollection get()
// never get here
return null;
}
+
+ /**
+ * The missing regular expression condition for value attributes.
+ *
+ *
+ * Sample: $("input").waitWhile(matchesValue("foo"), 12000)
+ *
+ *
+ * @param text
+ * The text that should be contained within the value attribute
+ * @return a Selenide {@link Condition}
+ * @see #matchValue(String)
+ */
+ public static Condition matchesValue(String text)
+ {
+ return matchValue(text);
+ }
+
+ /**
+ * The missing regular expression condition for value attributes.
+ *
+ *
+ * Sample: Assert that given element's value attribute matches given regular expression
+ * $("input").should(matchValue("Hello\s*John"))
+ *
+ *
+ * @param regex
+ * e.g. Kicked.*Chuck Norris - in this case ".*" can contain any characters including spaces, tabs, CR
+ * etc.
+ * @return a Selenide {@link Condition}
+ */
+ public static Condition matchValue(final String regex)
+ {
+ return new Condition("match value")
+ {
+ @Override
+ public boolean apply(WebElement element)
+ {
+ return Html.text.matches(element.getAttribute("value"), regex);
+ }
+
+ @Override
+ public String toString()
+ {
+ return name + " '" + regex + '\'';
+ }
+ };
+ }
+
+ /**
+ * The missing wrapper to generate screenshots and save the html source code if a jUnit assertion fails.
+ *
+ *
+ * Sample: Assert that page title is correct and dump the page source and a screenshot in case of a mismatch
+ * wrapAssertionError(()->{Assert.assertEquals("MyPageTitle", Selenide.title());});
+ *
+ *
+ * @param runnable
+ * The lambda containing an assertion
+ */
+ public static void wrapAssertionError(final Runnable runnable)
+ {
+ try
+ {
+ runnable.run();
+ }
+ catch (AssertionError e)
+ {
+ throw UIAssertionError.wrapThrowable(e, System.currentTimeMillis());
+ }
+ }
}
diff --git a/src/test/java/com/xceptance/neodymium/testclasses/allure/AllureSelenideListenerIsActiveForJava.java b/src/test/java/com/xceptance/neodymium/testclasses/allure/AllureSelenideListenerIsActiveForJava.java
new file mode 100644
index 000000000..ba68e58fd
--- /dev/null
+++ b/src/test/java/com/xceptance/neodymium/testclasses/allure/AllureSelenideListenerIsActiveForJava.java
@@ -0,0 +1,20 @@
+package com.xceptance.neodymium.testclasses.allure;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.codeborne.selenide.logevents.SelenideLogger;
+import com.xceptance.neodymium.NeodymiumRunner;
+import com.xceptance.neodymium.module.statement.browser.multibrowser.Browser;
+
+@RunWith(NeodymiumRunner.class)
+@Browser("Chrome_headless")
+public class AllureSelenideListenerIsActiveForJava
+{
+ @Test
+ public void testWaitingAnimationSelectorUnconfigured()
+ {
+ Assert.assertTrue(" AllureSelenide listener is not attached", SelenideLogger.hasListener(NeodymiumRunner.LISTENER_NAME));
+ }
+}
diff --git a/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberSupport.java b/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberSupport.java
index d5f7d6929..ba1b10562 100644
--- a/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberSupport.java
+++ b/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberSupport.java
@@ -2,6 +2,8 @@
import org.junit.Assert;
+import com.codeborne.selenide.logevents.SelenideLogger;
+import com.xceptance.neodymium.NeodymiumCucumberRunListener;
import com.xceptance.neodymium.util.Neodymium;
import com.xceptance.neodymium.util.WebDriverUtils;
@@ -9,6 +11,7 @@
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
+import cucumber.api.java.en.Then;
public class CucumberSupport
{
@@ -39,4 +42,10 @@ public void validateBrowser(String browserProfileName)
{
Assert.assertEquals(browserProfileName, Neodymium.getBrowserProfileName());
}
+
+ @Then("^validate the AllureSelenide listener is active$")
+ public void validateAllureSelenideListenerIsActive()
+ {
+ Assert.assertTrue(" AllureSelenide listener is not attached", SelenideLogger.hasListener(NeodymiumCucumberRunListener.LISTENER_NAME));
+ }
}
diff --git a/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.java b/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.java
new file mode 100644
index 000000000..bf5e12559
--- /dev/null
+++ b/src/test/java/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.java
@@ -0,0 +1,13 @@
+package com.xceptance.neodymium.testclasses.cucumber;
+
+import org.junit.runner.RunWith;
+
+import com.xceptance.neodymium.NeodymiumCucumberRunner;
+
+import cucumber.api.CucumberOptions;
+
+@RunWith(NeodymiumCucumberRunner.class)
+@CucumberOptions(features = "src/test/resources/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.feature", glue = "com/xceptance/neodymium/testclasses/cucumber", plugin = "null_summary")
+public class CucumberValidateAllureSelenideListenerIsActive
+{
+}
diff --git a/src/test/java/com/xceptance/neodymium/tests/AllureSelenideListenerTest.java b/src/test/java/com/xceptance/neodymium/tests/AllureSelenideListenerTest.java
new file mode 100644
index 000000000..2e99b5805
--- /dev/null
+++ b/src/test/java/com/xceptance/neodymium/tests/AllureSelenideListenerTest.java
@@ -0,0 +1,25 @@
+package com.xceptance.neodymium.tests;
+
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+import com.xceptance.neodymium.testclasses.allure.AllureSelenideListenerIsActiveForJava;
+import com.xceptance.neodymium.testclasses.cucumber.CucumberValidateAllureSelenideListenerIsActive;
+
+public class AllureSelenideListenerTest extends NeodymiumTest
+{
+ @Test
+ public void testAllureSelenideListenerIsActiveForCucumber()
+ {
+ Result result = JUnitCore.runClasses(CucumberValidateAllureSelenideListenerIsActive.class);
+ checkPass(result, 1, 0, 0);
+ }
+
+ @Test
+ public void testAllureSelenideListenerIsActiveForJava()
+ {
+ Result result = JUnitCore.runClasses(AllureSelenideListenerIsActiveForJava.class);
+ checkPass(result, 1, 0, 0);
+ }
+}
diff --git a/src/test/java/com/xceptance/neodymium/util/SelenideAddonsTest.java b/src/test/java/com/xceptance/neodymium/util/SelenideAddonsTest.java
new file mode 100644
index 000000000..bce3d29d6
--- /dev/null
+++ b/src/test/java/com/xceptance/neodymium/util/SelenideAddonsTest.java
@@ -0,0 +1,67 @@
+package com.xceptance.neodymium.util;
+
+import static com.codeborne.selenide.Selenide.$;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.codeborne.selenide.Selenide;
+import com.codeborne.selenide.ex.ElementShould;
+import com.codeborne.selenide.ex.UIAssertionError;
+import com.xceptance.neodymium.NeodymiumRunner;
+import com.xceptance.neodymium.module.statement.browser.multibrowser.Browser;
+
+@RunWith(NeodymiumRunner.class)
+@Browser("Chrome_headless")
+public class SelenideAddonsTest
+{
+ @Test
+ public void testMatchesValueCondition()
+ {
+ Selenide.open("https://blog.xceptance.com/");
+ $("#masthead .search-toggle").click();
+ $("#search-container .search-field").val("searchphrase").submit();
+
+ $("#content .search-field").should(SelenideAddons.matchesValue("earchphras"));
+ }
+
+ @Test
+ public void testMatchValueCondition()
+ {
+ Selenide.open("https://blog.xceptance.com/");
+ $("#masthead .search-toggle").click();
+ $("#search-container .search-field").val("searchphrase").submit();
+
+ $("#content .search-field").should(SelenideAddons.matchValue("^s.a.c.p.r.s.$"));
+ $("#content .search-field").should(SelenideAddons.matchValue("\\D+"));
+ }
+
+ @Test(expected = ElementShould.class)
+ public void testMatchValueConditionError()
+ {
+ Selenide.open("https://blog.xceptance.com/");
+ $("#masthead .search-toggle").click();
+ $("#search-container .search-field").val("searchphrase").submit();
+
+ $("#content .search-field").should(SelenideAddons.matchValue("\\d+"));
+ }
+
+ @Test()
+ public void testWrapAssertion()
+ {
+ Selenide.open("https://blog.xceptance.com/");
+ SelenideAddons.wrapAssertionError(() -> {
+ Assert.assertEquals("Passionate Testing | Xceptance Blog", Selenide.title());
+ });
+ }
+
+ @Test(expected = UIAssertionError.class)
+ public void testWrapAssertionError()
+ {
+ Selenide.open("https://blog.xceptance.com/");
+ SelenideAddons.wrapAssertionError(() -> {
+ Assert.assertEquals("MyPageTitle", Selenide.title());
+ });
+ }
+}
diff --git a/src/test/resources/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.feature b/src/test/resources/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.feature
new file mode 100644
index 000000000..5c5b33c33
--- /dev/null
+++ b/src/test/resources/com/xceptance/neodymium/testclasses/cucumber/CucumberValidateAllureSelenideListenerIsActive.feature
@@ -0,0 +1,8 @@
+@SetUpWithBrowserTag
+Feature: Set browser via tag
+
+ @Chrome_headless
+ Scenario: Set browsers
+ Given the browser "Chrome_headless" is setup
+ Then validate the AllureSelenide listener is active
+