Заработало после включение метода
.flush();
Заработало после включение метода
.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");
}
Ну я использую такое решение:
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)
Блин - СУПЕР, я помимо того что вышло прикрепить скриншот, еще пару полезных вещей для себя нашел
Еще больше Вы удивитесь, когда познаете, что можно прикрепить html страничку в виде аттача, а на ней можно сделать вообще что угодно(мы тут очень много разных форм делаем, от линковки тестов с багами до редактирования тестовых сценариев)
Теперь уже поделитесь, как вы вешаете Listenet в surfire plugin. У вас тесты выполняются по команде mvn test? Точнее в фазе test?
Ну тут уже, как говориться, “на вкус и цвет”.
Ну, например, есть обсуждение на этом же форуме
И все таки, коллеги. Если снимать скриншоты расставляя вызов метода
@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 просто не может снять скриншот.
Указанный эксепшен совсем не связан со скриншотами. Заводите новою тему с описанием проблемы.
П.С. Текущую тему закрываю, т.к. ответы были даны на любой вкус и цвет.