Skip to content

Commit

Permalink
Merge pull request #167 from giulong/release/v1.11.0
Browse files Browse the repository at this point in the history
Release/v1.11.0
  • Loading branch information
giulong authored May 27, 2024
2 parents 267690d + 33268a6 commit 1dba53f
Show file tree
Hide file tree
Showing 48 changed files with 3,358 additions and 127 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: Build
on:
push:
branches: [ "develop", "feature/**", "bugfix/**" ]
pull_request:
branches: [ "develop" ]
types: [ opened, reopened, edited ]

env:
EDGE_BINARY: /usr/bin/microsoft-edge
Expand Down
9 changes: 9 additions & 0 deletions DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ With that, just the framework's module is built, without running any test.
| unix | `./mvnw install -DskipTests -DskipSign -ntp -P framework-only` |
| windows | `mvnw.cmd install -DskipTests -DskipSign -ntp -P framework-only` |

## Checkstyle

The [checkstyle plugin](https://maven.apache.org/plugins/maven-checkstyle-plugin/) runs on every build. If you'd like to focus on code linting, you can run it with:

| OS | Command |
|---------|---------------------------------------------------------------------------|
| unix | `./mvnw checkstyle:checkstyle -DskipSign -DskipTests -ntp -pl spectrum` |
| windows | `mvnw.cmd checkstyle:checkstyle -DskipSign -DskipTests -ntp -pl spectrum` |

## Maven Profiles

These are the available profiles you can find in the [pom.xml](pom.xml):
Expand Down
13 changes: 10 additions & 3 deletions checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<module name="Checker">
<module name="Translation"/>
<module name="FileLength"/>
<module name="NewlineAtEndOfFile">
<property name="fileExtensions" value="java"/>
</module>

<module name="UniqueProperties"/>

Expand All @@ -38,6 +41,11 @@
</module>
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="EmptyLineSeparator">
<property name="allowMultipleEmptyLines" value="false"/>
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
<property name="tokens" value="CLASS_DEF, METHOD_DEF"/>
</module>
<module name="EmptyCatchBlock"/>
<module name="LeftCurly">
<property name="tokens" value="CLASS_DEF,INTERFACE_DEF,ANNOTATION_DEF,CTOR_DEF,METHOD_DEF"/>
Expand Down Expand Up @@ -84,9 +92,7 @@

<module name="IllegalImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports">
<property name="severity" value="warning"/>
</module>
<module name="UnusedImports"/>

<module name="OuterTypeFilename"/>
<module name="UpperEll"/>
Expand All @@ -107,6 +113,7 @@
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<module name="EnumValueName"/>

<module name="MethodLength">
<property name="severity" value="warning"/>
Expand Down
10 changes: 6 additions & 4 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ GEM
jekyll-seo-tag (~> 2.1)
minitest (5.20.0)
mutex_m (0.2.0)
nokogiri (1.16.2-arm64-darwin)
nokogiri (1.16.5-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.2-x64-mingw-ucrt)
nokogiri (1.16.5-x64-mingw-ucrt)
racc (~> 1.4)
nokogiri (1.16.2-x86_64-linux)
nokogiri (1.16.5-x86_64-linux)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
Expand All @@ -239,7 +239,8 @@ GEM
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.6)
rexml (3.2.8)
strscan (>= 3.0.9)
rouge (3.26.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
Expand All @@ -254,6 +255,7 @@ GEM
faraday (>= 0.17.3, < 3)
simpleidn (0.2.1)
unf (~> 0.1.4)
strscan (3.1.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
typhoeus (1.4.1)
Expand Down
107 changes: 97 additions & 10 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1185,20 +1185,82 @@ For such scenarios, Spectrum injects the `js` object you can use to perform basi
regular Selenium API. Each method available replicates the methods of the original
[WebElement](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebElement.html){:target="_blank"} interface.

Let's see how to use each method, you can check the
[Js javadocs](https://javadoc.io/doc/io.github.giulong/spectrum/latest/io/github/giulong/spectrum/utils/Js.html){:target="_blank"} for details:
You can check the
[Js javadocs](https://javadoc.io/doc/io.github.giulong/spectrum/latest/io/github/giulong/spectrum/utils/Js.html){:target="_blank"} for details and the
[JavascriptIT]({{ site.repository_url }}/it/src/test/java/io/github/giulong/spectrum/it/tests/JavascriptIT.java){:target="_blank"}
test to see real examples of all the `js` methods in action. For completeness, we're reporting one here:

{% include copyCode.html %}

```java
@Test
public void testInputFieldActions() {
driver.get(configuration.getApplication().getBaseUrl());
js.click(landingPage.getFormLoginLink());
loginPage.waitForPageLoading();
final WebElement usernameField = loginPage.getUsername();
final WebElement passwordField = loginPage.getPassword();
final WebElement form = loginPage.getForm();
js.sendKeys(usernameField, "tomsmith");
js.clear(usernameField);
assertTrue(js.getDomProperty(usernameField, "value").isEmpty());
js.sendKeys(usernameField, "tomsmith");
js.sendKeys(passwordField, "SuperSecretPassword!");
js.submit(form);
## click
pageLoadWait.until(urlToBe("https://the-internet.herokuapp.com/secure"));
assertEquals("https://the-internet.herokuapp.com/secure", driver.getCurrentUrl());
}
```

> ⚠️ **Methods not supported**<br/>
> Currently, the `js` object doesn't support these WebElement methods:
> * getAriaRole
> * getAccessibleName
> * getScreenshotAs

---

# JsWebElement

If you find yourself frequently running Javascript to interact with a particular web element,
you should probably annotate it with `@JsWebElement` like this:

{% include copyCode.html %}

```java
js.click(webElement);
// applied on a single WebElement
@FindBy(tagName = "h1")
@JsWebElement
private WebElement title;
// applied on a list of WebElements, the annotation is the same
@FindBys({
@FindBy(id = "wrapper-id"),
@FindBy(tagName = "input")
})
@JsWebElement
private List<WebElement> inputFields;
```

You can check the
[JavascriptIT]({{ site.repository_url }}/it/src/test/java/io/github/giulong/spectrum/it/tests/JavascriptIT.java){:target="_blank"}
test to see real examples of all the `js` methods in action.
By applying the `@JsWebElement` annotation, each interaction with the annotated web element will be executed in the corresponding Javascript
way. This means you don't need to do anything programmatically, the annotation on the field is enough:
by calling any regular webElement method on the fields above, such as `title.getText()` or `inputFields.getFirst().sendKeys("username")`,
the execution will actually be delegated to the `js` object, and will behave as explained in the [Javascript Executor](#javascript-executor) paragraph.
This means that:

* `title.getText()` will behave as `js.getText(title)`
* `inputFields.getFirst().sendKeys("username")` will behave as `js.sendKeys(inputFields.getFirst(), "username")`

Remember: you just need to annotate the webElement(s) with `@JsWebElement` and Spectrum will take care of interacting with the annotated
webElement(s) via Javascript. That's it!

Be sure to check the [JsWebElementIT]({{ site.repository_url }}/it/src/test/java/io/github/giulong/spectrum/it/tests/JsWebElementIT.java){:target="_blank"}
to see some working example tests.

---

Expand Down Expand Up @@ -2465,10 +2527,22 @@ html:
```

For the sake of completeness, the output file was manually copied [here](assets/miscellanea/summary.html){:target="_blank"}.
This is what it looks like when opened in a driver:
This is what it looks like when opened in a browser:

![Html Summary Reporter](assets/images/html-summary.png)

Beside the default template, these are already available, you just need to pick the corresponding template:

* [summary-pies.html](assets/miscellanea/summary-pies.html){:target="_blank"} that leverages [Google Charts](https://developers.google.com/chart){:target="_blank"}

{% include copyCode.html %}

```yaml
html:
template: templates/summary-pies.html
```

![Html Summary Pies Reporter](assets/images/html-summary-pies.png)
---

# TestBook - Coverage
Expand Down Expand Up @@ -2838,16 +2912,29 @@ This is the internal

```yaml
html:
template: templates/testBook.html
template: templates/testbook.html
output: ${testBookReportOutput}/testBook-${timestamp}.html
retention: { }
```

For the sake of completeness, the output file was manually copied [here](assets/miscellanea/testbook.html){:target="_blank"}.
This is what it looks like when opened in a driver:
This is what it looks like when opened in a browser:

![Html TestBook Reporter](assets/images/html-testbook.png)

Beside the default template, these are already available, you just need to pick the corresponding template:

* [testbook-pies.html](assets/miscellanea/testbook-pies.html){:target="_blank"} that leverages [Google Charts](https://developers.google.com/chart){:target="_blank"}

{% include copyCode.html %}

```yaml
html:
template: templates/testbook-pies.html
```

![Html TestBook Pies Reporter](assets/images/html-testbook-pies.png)

## Default TestBook

The one below is the testBook in the internal
Expand Down
Binary file added docs/assets/images/html-summary-pies.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/images/html-summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/html-testbook-pies.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/images/html-testbook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/images/spectrum-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
273 changes: 273 additions & 0 deletions docs/assets/miscellanea/summary-pies.html

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion docs/assets/miscellanea/summary.html

Large diffs are not rendered by default.

649 changes: 649 additions & 0 deletions docs/assets/miscellanea/testbook-pies.html

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion docs/assets/miscellanea/testbook.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/json-schemas/1.11.0/Configuration-schema.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions it-appium/src/test/resources/configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ drivers:
uiAutomator2:
capabilities:
app: src/test/resources/hello-world.apk
# Instead of providing the 'app' capability, the two below can be used if the app is already installed on the device
#appPackage: com.example.helloworld
#appActivity: MainActivity
avd: phone
avdArgs: -no-window -no-audio -no-boot-anim -no-snapshot
uiautomator2ServerInstallTimeout: 60000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import java.util.List;

import static org.openqa.selenium.support.ui.ExpectedConditions.*;

@Getter
@Endpoint("checkboxes")
@SuppressWarnings("unused")
Expand All @@ -21,4 +23,13 @@ public class JsCheckboxPage extends SpectrumPage<JsCheckboxPage, Void> {
})
@JsWebElement
private List<WebElement> checkboxes;

@Override
public JsCheckboxPage waitForPageLoading() {
pageLoadWait.until(and(
urlToBe("https://the-internet.herokuapp.com/checkboxes"),
visibilityOfAllElements(checkboxes)));

return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ public class JsLandingPage extends SpectrumPage<JsLandingPage, Void> {
@FindBy(linkText = "Checkboxes")
@JsWebElement
private WebElement checkboxLink;

@FindBy(linkText = "Form Authentication")
@JsWebElement
private WebElement formLoginLink;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.github.giulong.spectrum.it.pages;

import io.github.giulong.spectrum.SpectrumPage;
import io.github.giulong.spectrum.interfaces.Endpoint;
import io.github.giulong.spectrum.interfaces.JsWebElement;
import io.github.giulong.spectrum.it.data.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedCondition;

import static org.openqa.selenium.By.id;

@Getter
@Slf4j
@Endpoint("login")
@SuppressWarnings("unused")
public class JsLoginPage extends SpectrumPage<JsLoginPage, Void> {

@FindBy(id = "flash")
@JsWebElement
private WebElement errorMessage;

@FindBy(id = "username")
@JsWebElement
private WebElement username;

@FindBy(id = "password")
@JsWebElement
private WebElement password;

@FindBy(id = "login")
@JsWebElement
private WebElement form;

@FindBy(id = "content")
@JsWebElement
private WebElement contentDiv;

@FindBy(className = "subheader")
@JsWebElement
private WebElement subHeader;

@Override
public JsLoginPage waitForPageLoading() {
log.info("Wait for page loading: waiting for errorMessage to disappear");
implicitWait.until((ExpectedCondition<Boolean>) driver -> isNotPresent(id("flash")));

return this;
}

public JsLoginPage loginWith(final Data.User user) {
clearAndSendKeys(username, user.getName());
clearAndSendKeys(password, user.getPassword());

form.submit();
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.giulong.spectrum.it.pages;

import io.github.giulong.spectrum.SpectrumPage;
import io.github.giulong.spectrum.interfaces.Endpoint;
import io.github.giulong.spectrum.interfaces.JsWebElement;
import lombok.Getter;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

@Getter
@Endpoint("shadowdom")
@SuppressWarnings("unused")
public class JsShadowDomPage extends SpectrumPage<JsShadowDomPage, Void> {

@FindBy(tagName = "my-paragraph")
@JsWebElement
private WebElement myParagraph;

@FindBy(css = "span[slot=\"my-text\"]")
@JsWebElement
private WebElement span;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@
@SuppressWarnings("unused")
public class LandingPage extends SpectrumPage<LandingPage, Void> {

@FindBy(id = "login")
private WebElement form;

@FindBy(tagName = "h1")
private WebElement title;

@FindBy(linkText = "Checkboxes")
private WebElement checkboxLink;

@FindBy(linkText = "Form Authentication")
private WebElement formLoginLink;
}
Loading

0 comments on commit 1dba53f

Please sign in to comment.