rovner / screenshot-assert

Screenshot assertions with allure reporting

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Screenshot assert

Java library for screenshot based testing with Selenium and Allure reporting
Benefits:

  • Easy screenshot comparison for page elements from the box.
  • Possibility to ignore different diffs by element, area or diff hash code.
  • Allure report integration from the box.
  • Easy customization of any part.
  • Possibility to take whole page screenshots on mobile devices.

Dependency

Maven:

<dependency>
    <groupId>io.github.rovner</groupId>
    <artifactId>screenshot-assert-core</artifactId>
    <version>1.0.0</version>
    <scope>test</scope>
</dependency>
<!--extension for junit 5-->
<dependency>
    <groupId>io.github.rovner</groupId>
    <artifactId>screenshot-assert-junit5</artifactId>
    <version>1.0.0</version>
    <scope>test</scope>
</dependency>

Gradle:

testImplementation 'io.github.rovner:screenshot-assert-core:1.0.0'
//extension for junit 5
testImplementation 'io.github.rovner:screenshot-assert-junit5:1.0.0'

Usage

  • Junit5 with hard assertions
//junit5 with hard assertions
@RegisterExtension
ScreenshotAssertExtension screenshotAssert = new ScreenshotAssertExtension(()->webDriver);

@Test
void test(){
    //test actions 
    screenshotAssert.assertThat(screenshotOfViewport())
        .isEqualToReferenceId("some_reference_id");
}
  • Junit5 with soft assertions
@RegisterExtension
private final SoftScreenshotAssertExtension softScreenshotAssert = new SoftScreenshotAssertExtension(()->wd);

@Test
void test(){
    //test actions
    screenshotAssert.assertThat(screenshotOfElementFoundBy(cssSelector(".element-1")))
        .isEqualToReferenceId("element_reference_1");
    screenshotAssert.assertThat(screenshotOfElementFoundBy(cssSelector(".element-2")))
        .isEqualToReferenceId("element_reference_2");
    }
  • No framework with hard assertions
ScreenshotAssertBuilder screenshotAssert = ScreenshotAssertBuilder.builder()
    .setWebDriver(wd)
    .setReferenceStorage(new DefaultReferenceStorage(Paths.get("some/path/to/references")));

@Test
void test(){
    //test actions
    screenshotAssert.assertThat(screenshotOfViewport())
        .isEqualToReferenceId("some_reference_id");
    }
  • No framework with soft assertions
ScreenshotAssertBuilder screenshotAssert = ScreenshotAssertBuilder.builder()
    .setWebDriver(wd)
    .setReferenceStorage(new DefaultReferenceStorage(Paths.get("some/path/to/references")))
    .setSoft(true);

@Test
void test(){
    //test actions
    screenshotAssert.assertThat(screenshotOfElementFoundBy(cssSelector(".element-1")))
        .setReferenceStorage("element_reference_1");
    screenshotAssert.assertThat(screenshotOfElementFoundBy(cssSelector(".element-2")))
        .isEqualToReferenceId("element_reference_2");
}

See more in examples

Types of screenshots

  • Of viewport (part of the document visible in window).
screenshotAssert.assertThat(Screenshots.screenshotOfViewport())
    .isEqualToReferenceId("id");
  • Of whole page (document). Be cautious with method because it scrolls page and could change it state.
screenshotAssert.assertThat(Screenshots.screenshotOfWholePage())
    .isEqualToReferenceId("id");
  • Of some area by coordinates in the view port. Coordinates are relative to the viewport.
screenshotAssert.assertThat(Screenshots.screenshotOfViewportArea(20,140,640,120))
    .isEqualToReferenceId("id");
  • Of some area by coordinates in the whole page. Coordinates are relative to the document. Be cautious with method because it scrolls page and could change it state.
screenshotAssert.assertThat(Screenshots.screenshotOfOageArea(20,140,640,120))
    .isEqualToReferenceId("id");
  • Of web element (for browsers).
WebElement element = webDriver.findElement(cssSelector(".element"));
screenshotAssert.assertThat(Screenshots.screenshotOfElement(element))
    .isEqualToReferenceId("id");
  • Of web element locatable by selector (for browsers).
screenshotAssert.assertThat(Screenshots.screenshotOfElementFoundBy(cssSelector(".element")))
    .isEqualToReferenceId("id");
  • Of native element (for native apps).
WebElement element = webDriver.findElement(id("id"));
screenshotAssert.assertThat(Screenshots.screenshotOfNativeElement(element))
    .isEqualToReferenceId("id");
  • Of native element locatable by selector (for native apps).
screenshotAssert.assertThat(Screenshots.screenshotOfNativeElementFoundBy(id("id")))
    .isEqualToReferenceId("id");

See all types

Types of ignoring

  • Of viewport area.
screenshotAssert.assertThat(screenshotOfViewport())
    .ignoring(area(10, 10, 40, 50))
    .ignoring(area(new Rectangle(60, 30, 10, 20))) //pay attention to order of arguments
    .isEqualToReferenceId("id");
  • Of element/elements.
WebElement element=webDriver.findElement(cssSelector(".element"));
screenshotAssert.assertThat(screenshotOfViewport())
    .ignoring(element(element))
    .isEqualToReferenceId("id");
  • Of elements found by selector.
screenshotAssert.assertThat(screenshotOfViewport())
    .ignoring(elementBy(cssSelector(".element")))
    .isEqualToReferenceId("id");
  • Of diff hash codes.
screenshotAssert.assertThat(screenshotOfViewport())
    .ignoring(hashes(123,321)) //diff hash could be found in allure report
    .isEqualToReferenceId("id");

Configuration

Add file named screenshot-assert.properties to resources dir or use -D properties

  • Property: io.github.rovner.screenshot.assert.is.update.reference.image.
    Default: false.
    Whatever save actual image as reference when there is difference. Useful to update images after changes.

  • Property: io.github.rovner.screenshot.assert.is.save.reference.image.when.missing.
    Default: true.
    Whatever save actual image as reference when no reference exists. Recommended to set to false on CI.

  • Property: io.github.rovner.screenshot.assert.is.soft.
    Default: false.
    Makes all assertions soft.

  • Property: io.github.rovner.screenshot.assert.references.base.dir
    Default: src/test/resources/references
    [Only for junit5] Base directory where screenshots will be stored.

Mobile browsers

Screenshots provided by appium from mobile devices besides the viewport contain additional parts(phone bar, browser bar) as well. The height and location of these parts are different on different browsers/devices so such configurations should be done in the target test/framework with knowledge of what devices are used. Here are some examples of how it could be achieved:

//iphone 13
@RegisterExtension
private final ScreenshotAssertExtension screenshotAssert = new ScreenshotAssertExtension(() -> wd)
        .scrollSleepTimeout(ofMillis(100))
        .viewportCropper(aggregating(fixedHeaderCutting(140), floatingFooterCutting()));

//ipad 9th generation
@RegisterExtension
private final ScreenshotAssertExtension screenshotAssert = new ScreenshotAssertExtension(() -> wd)
        .scrollSleepTimeout(ofMillis(100))
        .scrollMarginPixels(16)
        .viewportCropper(floatingHeaderCutting());

//android Pixel 5
@RegisterExtension
private final ScreenshotAssertExtension screenshotAssert = new ScreenshotAssertExtension(() -> wd)
        .scrollSleepTimeout(ofSeconds(1))
        .scrollMarginPixels(8)
        .viewportCropper(aggregating(capabilities(), floatingHeaderCutting()));

//android Pixel C
@RegisterExtension
private final ScreenshotAssertExtension screenshotAssert = new ScreenshotAssertExtension(() -> wd)
        .scrollSleepTimeout(ofSeconds(1))
        .scrollMarginPixels(60)
        .viewportCropper(aggregating(fixedFooterCutting(120), floatingHeaderCutting()));

//selecting cropper in runtime
@RegisterExtension
private final ScreenshotAssertExtension screenshotAssert = new ScreenshotAssertExtension(() -> wd)
        .scrollSleepTimeout(ofSeconds(500))
        .viewportCropper(matching()
            .match(isDesktop(), desktop())
            .match(isIos().and(isIpad()).and(isSafari()), floatingHeaderCutting())
            .match(isIos().and(isIphone()).and(isSafari()), aggregating(fixedHeaderCutting(140), floatingFooterCutting()))
            .match(isAndroid(), aggregating(capabilities(), floatingHeaderCutting()))
        );

See more in examples

Customizing

About

Screenshot assertions with allure reporting


Languages

Language:Java 100.0%