[Resolved] Как прикрепить скриншоты проваленных методов в Allure.

Заработало после включение метода

.flush();

Каков ваш итоговый, рабочий вариант?

@Attachment(value = "ScreenshotAttachment", type = "image/png")
public byte[] createAttachment() {
    return captureScreenShot();
}


private byte[] captureScreenShot() {
    try {
        BufferedImage image  = new AShot().shootingStrategy(new ViewportPastingStrategy(5)).takeScreenshot(driver).getImage();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        baos.flush();
        byte[] imageInByte = baos.toByteArray();
        baos.close();
        return imageInByte;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "Attachment Content Empty, can't create screenshot".getBytes();
}

Правда теперь придется решать новую проблему. Невзирая на Ashot, ff и chrome по разному снимают скриншоты - но это уже тема для нового обсуждения.

Так а как вы данный метод в принципе запускаете?
Я пробовал так:

@AfterMethod(alwaysRun = true)
    public void afterMethod(ITestResult result) {
        if (!result.isSuccess()) {
            screenshoter = new Screenshoter(driver);
            screenshoter.takeFullPageShotForFailedTests();
        }
    }

takeFullPageShotForFailedTests() - ваш метод помещен в класс с другими методами скриншотинга.

Но нифига не выходит.

Вы наверное делали через лиснер. Если да то покажите код лиснера и как его подключаете. Я только соскочил с JUnit и лиснеры для меня в новинку

Нет листинер я еще не делал. И не уверен, что буду, а вот @Taras похоже делал именно, через Listener.

Такой вот еще вопрос о лиснерах:
Согласно этой доке - TestNG подключаю лиснер.
Создаю в проекте файл src/main/resources/META-INF/services/org.testng.ITestNGListener
В файле пишу референс класса который имплементит лиснер - com.me.someframework.core.listeners.OnFailureListener

Вот с таким содержанием работет:

public class OnFailureListener extends TestListenerAdapter {

    @Override
    public void onTestFailure(ITestResult tr) {
        System.out.println("INSIDE onTestFailure");
    }
}

Теперь вопрос - как передать туда драйвер?

Вот базовый класс от которого наследуются все тестовые классы:

public abstract class BaseTest {

    protected WebDriver driver;
    protected PropertyStorage propertyStorage = PropertyStorage.getInstance();
    protected Screenshoter screenshoter;

    DriverProvider driverProvider = new DriverProvider();

    @BeforeClass(alwaysRun = true)
    public void beforeClass() {
        driverProvider.createDriver();
    }

    @BeforeMethod(alwaysRun = true)
    public void beforeMethod() {
        driver = driverProvider.getDriver();
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
        driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
        driver.manage().deleteAllCookies();
    }

    @AfterMethod(alwaysRun = true)
    public void afterMethod() {
        driver.manage().deleteAllCookies();
    }


    @AfterClass(alwaysRun = true)
    public void afterClass() {
        driver.quit();
    }

}

Есть класс Screenshooter в котором есть метод

@Attachment(value = "ScreenshotAttachment", type = "image/png")
    public byte[] takeFullPageShotForFailedTests() {
        return captureScreenShot();
    }

    private byte[] captureScreenShot() {
        try {
            BufferedImage image  = new AShot().shootingStrategy(new ViewportPastingStrategy(5)).takeScreenshot(driver).getImage();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", baos);
            baos.flush();
            byte[] imageInByte = baos.toByteArray();
            baos.close();
            return imageInByte;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "Attachment Content Empty, can't create screenshot".getBytes();
    }

Либо дергать static getter ThreadLocal контейнера, либо можно засетить драйвер в контекст TestNG:

@BeforeMethod
public void setUp(final ITestContext context) {
    context.setAttribute("driverKey", driver);
}

public void onTestFailure(final ITestResult result) {
    WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driverKey");
}
2 Likes

Ну я использую такое решение:

import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

import static <some_package>.Utils.makeScreenshot;

public class AllureOnFailListener implements ITestListener {
    @Override
    public void onTestStart(ITestResult result) {}

    @Override
    public void onTestSuccess(ITestResult result) {}

    @Override
    public void onTestFailure(ITestResult result) {
        makeScreenshot("Failure screenshot");
    }

    @Override
    public void onTestSkipped(ITestResult result) {}

    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
        makeScreenshot("Failure screenshot");
    }

    @Override
    public void onStart(ITestContext context) {}

    @Override
    public void onFinish(ITestContext context) {}
}

Где makeScreenshot(String) статик метод из Utils.

import org.openqa.selenium.OutputType;
import ru.yandex.qatools.allure.annotations.Attachment;

public final class Utils {
    private Utils() {}

    @Attachment(value = "{0}", type = "image/png")
    public static byte[] makeScreenshot(String name) {
        return (TakesScreenshot) <Thread local instance of the WebDriver>.getScreenshotAs(OutputType.BYTES);
    }
}

Дальше вешаю этот листенер в pom - surefire plugin, либо аннотирую тестовый класс @Listeners(AllureOnFailListener.class)

3 Likes

Блин - СУПЕР, я помимо того что вышло прикрепить скриншот, еще пару полезных вещей для себя нашел :slight_smile:

Еще больше Вы удивитесь, когда познаете, что можно прикрепить html страничку в виде аттача, а на ней можно сделать вообще что угодно(мы тут очень много разных форм делаем, от линковки тестов с багами до редактирования тестовых сценариев)

Теперь уже поделитесь, как вы вешаете Listenet в surfire plugin. У вас тесты выполняются по команде mvn test? Точнее в фазе test?

А зачем гадить лишними строками в ваш пом файл?
TestNG - разве так подключать не удобнее?

Ну тут уже, как говориться, “на вкус и цвет”.

Ну, например, есть обсуждение на этом же форуме

И все таки, коллеги. Если снимать скриншоты расставляя вызов метода

@Attachment(value = "PNG Attachment", type = "image/png")
public byte[] createAttachment() {
    return captureScreenShot();
}

Можно ли как то в allure присвоить ему уникальное имя - например Searh, Change и прочее - что бы в отчете - видеть к какой именно операции относится скриншот. При том, что тестовый метод всегда называется одинаково - используется DataProvider.

Сорри, вроде увидел. Осталось только прикрутить проверку на driver == null)

Хотя теперь возникла проблема вот такая

ClassCastException: java.lang.Double cannot be cast to java.lang.Long

Насколько я понимаю, при удаленном запуске IE просто не может снять скриншот.

Указанный эксепшен совсем не связан со скриншотами. Заводите новою тему с описанием проблемы.
П.С. Текущую тему закрываю, т.к. ответы были даны на любой вкус и цвет.

1 Like