diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/Click.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/Click.java index af7f0c1509..247b1e84b8 100644 --- a/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/Click.java +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/Click.java @@ -1,5 +1,6 @@ package net.serenitybdd.screenplay.actions; +import com.google.common.collect.Lists; import net.serenitybdd.core.pages.WebElementFacade; import net.serenitybdd.screenplay.Action; import net.serenitybdd.screenplay.targets.Target; @@ -22,7 +23,7 @@ public static Action on(WebElementFacade element) { } public static Action on(By... locators) { - return instrumented(ClickOnBy.class, locators); + return instrumented(ClickOnBy.class, Lists.newArrayList(locators)); } } diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/ClickOnBy.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/ClickOnBy.java index cc828cf112..61d976f59b 100644 --- a/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/ClickOnBy.java +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/actions/ClickOnBy.java @@ -4,6 +4,8 @@ import net.thucydides.core.annotations.Step; import org.openqa.selenium.By; +import java.util.List; + public class ClickOnBy extends ByAction { @Step("{0} clicks on #target") @@ -15,4 +17,8 @@ public ClickOnBy(By... locators) { super(locators); } + public ClickOnBy(List locators) { + super(locators.toArray(new By[]{})); + } + } diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/UnresolvedTargetWebElementState.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/UnresolvedTargetWebElementState.java new file mode 100644 index 0000000000..eec0693d7e --- /dev/null +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/UnresolvedTargetWebElementState.java @@ -0,0 +1,144 @@ +package net.serenitybdd.screenplay.questions; + +import net.serenitybdd.core.pages.WebElementState; + +/** + * Created by john on 14/01/2016. + */ +public class UnresolvedTargetWebElementState implements WebElementState { + + private final String name; + + public UnresolvedTargetWebElementState(String name) { + this.name = name; + } + + @Override + public String toString() { + return "not so"; + } + + @Override + public boolean isVisible() { + return false; + } + + @Override + public boolean isCurrentlyVisible() { + return false; + } + + @Override + public boolean isCurrentlyEnabled() { + return false; + } + + @Override + public void shouldBeVisible() { + throw new AssertionError("Element should be visible"); + } + + @Override + public void shouldBeCurrentlyVisible() { + throw new AssertionError("Element should be visible"); + } + + @Override + public void shouldNotBeVisible() {} + + @Override + public void shouldNotBeCurrentlyVisible() {} + + @Override + public boolean hasFocus() { + return false; + } + + @Override + public boolean containsText(String value) { + return false; + } + + @Override + public boolean containsOnlyText(String value) { + return false; + } + + @Override + public boolean containsSelectOption(String value) { + return false; + } + + @Override + public void shouldContainText(String textValue) { + throw new AssertionError("Element should contain text " + textValue); + } + + @Override + public void shouldContainOnlyText(String textValue) { + throw new AssertionError("Element should contain text " + textValue); + } + + @Override + public void shouldContainSelectedOption(String textValue) { + throw new AssertionError("Element should contain selected option " + textValue); + } + + @Override + public void shouldNotContainText(String textValue) {} + + @Override + public void shouldBeEnabled() { + throw new AssertionError("Element should be enabled"); + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public void shouldNotBeEnabled() { + + } + + @Override + public String getSelectedVisibleTextValue() { + return null; + } + + @Override + public String getSelectedValue() { + return null; + } + + @Override + public boolean isPresent() { + return false; + } + + @Override + public void shouldBePresent() { + throw new AssertionError("Element should be present"); + } + + @Override + public void shouldNotBePresent() { + + } + + @Override + public boolean isSelected() { + return false; + } + + @Override + public String getTextValue() { + return null; + } + + @Override + public WebElementState expect(String errorMessage) { + return null; + } +} diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/WebElementQuestion.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/WebElementQuestion.java index 3f5bae3d2c..075991e367 100644 --- a/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/WebElementQuestion.java +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/questions/WebElementQuestion.java @@ -3,8 +3,11 @@ import net.serenitybdd.core.pages.WebElementState; import net.serenitybdd.screenplay.Actor; import net.serenitybdd.screenplay.Question; +import net.serenitybdd.screenplay.annotations.Subject; import net.serenitybdd.screenplay.targets.Target; +import org.openqa.selenium.NoSuchElementException; +@Subject("#target") public class WebElementQuestion implements Question { private final Target target; @@ -27,6 +30,10 @@ public static Question the(Target target) { @Override public WebElementState answeredBy(Actor actor) { - return target.resolveFor(actor); + try { + return target.resolveFor(actor); + } catch (NoSuchElementException unresolvedTarget) { + return new UnresolvedTargetWebElementState(target.getName()); + } } } diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/ByTarget.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/ByTarget.java index f76cae3746..ba3314a1e5 100644 --- a/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/ByTarget.java +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/ByTarget.java @@ -26,6 +26,16 @@ public List resolveAllFor(Actor actor) { return resolver.findAll(locator); } + + public XPathOrCssTarget of(String... parameters) { + throw new UnsupportedOperationException("The of() method is not supported for By-type Targets"); + } + + @Override + public String getCssOrXPathSelector() { + throw new UnsupportedOperationException("The getCssOrXPathSelector() method is not supported for By-type Targets"); + } + public ByTarget called(String name) { return new ByTarget(name, locator); } diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/Target.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/Target.java index 5e58f6d115..f22fa5882a 100644 --- a/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/Target.java +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/Target.java @@ -27,4 +27,14 @@ public static TargetBuilder the(String targetElementName) { public abstract List resolveAllFor(Actor actor); public abstract Target called(String name); + + public abstract Target of(String... parameters); + + public abstract String getCssOrXPathSelector(); + + public String getName() { + return targetElementName; + } + + } diff --git a/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/XPathOrCssTarget.java b/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/XPathOrCssTarget.java index 636c13d38b..cf0f2c14fc 100644 --- a/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/XPathOrCssTarget.java +++ b/browse-the-web/src/main/java/net/serenitybdd/screenplay/targets/XPathOrCssTarget.java @@ -25,14 +25,18 @@ public List resolveAllFor(Actor actor) { return resolver.findAll(cssOrXPathSelector); } - public XPathOrCssTarget of(String... parameters) { + public Target of(String... parameters) { return new XPathOrCssTarget(targetElementName, instantiated(cssOrXPathSelector, parameters)); } - public XPathOrCssTarget called(String name) { + public Target called(String name) { return new XPathOrCssTarget(name, cssOrXPathSelector); } + public String getCssOrXPathSelector() { + return cssOrXPathSelector; + } + private String instantiated(String cssOrXPathSelector, String[] parameters) { return new TargetSelectorWithVariables(cssOrXPathSelector).resolvedWith(parameters); } diff --git a/serenity-core/src/main/java/net/thucydides/core/steps/StepEventBus.java b/serenity-core/src/main/java/net/thucydides/core/steps/StepEventBus.java index 955e7b7f66..dcab58320f 100644 --- a/serenity-core/src/main/java/net/thucydides/core/steps/StepEventBus.java +++ b/serenity-core/src/main/java/net/thucydides/core/steps/StepEventBus.java @@ -375,6 +375,9 @@ public void dropAllListeners() { } public boolean webdriverCallsAreSuspended() { + if (softAssertsActive()) { + return !webdriverSuspensions.isEmpty(); + } return aStepInTheCurrentTestHasFailed() || !webdriverSuspensions.isEmpty(); } diff --git a/serenity-core/src/main/java/net/thucydides/core/steps/StepFailure.java b/serenity-core/src/main/java/net/thucydides/core/steps/StepFailure.java index 99fe08ad6d..1ccfd6a2ab 100644 --- a/serenity-core/src/main/java/net/thucydides/core/steps/StepFailure.java +++ b/serenity-core/src/main/java/net/thucydides/core/steps/StepFailure.java @@ -26,7 +26,7 @@ public StepFailure(final ExecutedStepDescription description, final Throwable ca if (cause instanceof SerenityManagedException) { this.exceptionClass = ((SerenityManagedException)cause).getExceptionClass(); this.message = cause.getMessage(); - this.stackTraceElements = ((SerenityManagedException)cause).getStackTrace(); + this.stackTraceElements = cause.getStackTrace(); } else { this.exceptionClass = cause.getClass(); this.message = cause.getMessage();