Как я могу сохранить снимок экрана из объекта в строку и сохранить изображение на листе Excel в selenium WebDriver?

#java #excel #selenium #automation #apache-poi

Вопрос:

У меня есть простая программа selenium WebDriver, которая считывает данные файла excel и выполняет функции входа в систему.

Я требую делать снимок экрана всякий раз, когда тестовый случай завершается неудачно, и сохранять его в ячейке рабочего листа Excel.

Чтобы выполнить чтение и запись excel, я уже создал код. Я также написал программу, которая делает скриншоты и сохраняет их с уникальными именами. Эта программа находится в отдельном классе в пакете утилит, который я вызываю в ОСНОВНОЙ метод, используя его экземпляр/объект.

Я хочу сохранить объект класса FailedTestScreenCapture в строковую переменную и извлечь изображение, полученное из этого объекта, а затем сохранить его на листе Excel.

Ниже приведен код, который я создал для захвата скриншотов и сохранения их с уникальными именами.

 package utilities;  import java.io.File; import java.util.UUID; import org.openqa.selenium.io.FileHandler;  import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver;  public class FailedTestScreenCapture implements MethodRule {  WebDriver driver;   public FailedTestScreenCapture(WebDriver driver) {  this.driver = driver;  }   public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object obj) {  // Auto-generated method stub  return new Statement() {  @Override  public void evaluate() throws Throwable {  try {  statement.evaluate();  } catch (Throwable t) {  // handle exception  captureScreen(frameworkMethod.getName());  throw t;  }  }   public void captureScreen(String screenShot) {  // creating a screenshot method  try {  TakesScreenshot ts = (TakesScreenshot) driver;  File source = ts.getScreenshotAs(OutputType.FILE);  screenShot  = UUID.randomUUID().toString();  FileHandler.copy(source, new File("./Screenshots/"   screenShot   ".jpg"));  } catch (Exception e) {   System.out.println("An exception occured while taking the screenshot"   e.getMessage());  }  }  };  } }  

Ниже приведен код, который считывает и записывает рабочий лист Excel.

 package view;  import java.io.IOException; import java.time.Duration; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver;  import utilities.ExcelUtils; import utilities.FailedTestScreenCapture; import utilities.Constants;  public class OTMGeneral {  static WebDriver driver;    // creating object of ExcelUtils class  static ExcelUtils excelUtils = new ExcelUtils();  static FailedTestScreenCapture failedTstCase = new FailedTestScreenCapture(driver);   // using the constants class values for excel file path  static String excelFilePath = Constants.Path_TestData   Constants.File_TestData;   public static void main(String args[]) throws IOException {  System.setProperty("webdriver.chrome.driver", Constants.chromeDriverPath);  driver = new ChromeDriver();   // maximize the browser screen  driver.manage().window().maximize();  driver.navigate().to(Constants.BaseUrl);   // wait for the browser to load resources  driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));   // Identify the WebElements for OTM Login  WebElement continueBtn = driver.findElement(By.xpath("/html/body/div[1]/div/div/div[2]/button"));  WebElement loginBtn = driver.findElement(By.xpath("/html/body/header/div/div/nav/div/ul/li[2]/a"));   // landing page pop-up message  WebElement popupMsg = driver.findElement(By.xpath("/html/body/div[1]/div/div"));   // click the sing-in button  if (popupMsg.isDisplayed()) {  // if the pop-up is displayed, click the continue button  continueBtn.click();   // wait for page to come back to landing page after continue button is clicked  driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));   // click the login button  loginBtn.click();  } else {  loginBtn.click();  }   WebElement email = driver.findElement(By.id("Email"));  WebElement pwd = driver.findElement(By.id("Password"));  WebElement signInBtn = driver.findElement(By.id("btnlogin"));   // calling ExcelUtils class method to initialize the workbook and sheet  excelUtils.setExcelFile(excelFilePath, "Login_Data");   for (int i = 1; i lt;= excelUtils.getRowCountInSheet(); i  ) {   if (i gt; 1) {  // Handling staled elements by refreshing the screen  driver.navigate().refresh();  driver.findElement(By.xpath("/html/body/header/div/div/nav/div/ul/li[2]/a")).click();   driver.findElement(By.id("Email")).sendKeys(excelUtils.getCellData(i, 0));  driver.findElement(By.id("Password")).sendKeys(excelUtils.getCellData(i, 1));   driver.findElement(By.id("btnlogin")).click();   } else {   driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));  // Enter the value read from excel in email and password fields  email.sendKeys(excelUtils.getCellData(i, 0));  pwd.sendKeys(excelUtils.getCellData(i, 1));   // click on login button  signInBtn.click();  }   // wait after login button clicked  driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));   // check for login pass or fail  boolean helloCustomer = driver.findElement(By.xpath("/html/body/header/div/div/nav/div/ul/li[1]/a"))  .getText().equalsIgnoreCase("Regístrate");  System.out.println(helloCustomer);   if (!helloCustomer) {   // capture the result in the excel sheet  excelUtils.setCellValue(i, 2, "Pass", excelFilePath);  System.out.println("login pass");  // Identify logout button  WebElement logout = driver.findElement(By.id("logout"));  logout.click();  } else {  excelUtils.setCellValue(i, 2, "Fail", excelFilePath);  System.out.println("login fail");  // capture screenshot when a test case fails  excelUtils.setCellValue(i, 3, failedTstCase.toString(), excelFilePath);  }   // wait for page to come back to registration page after logout button is  // clicked  driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));  }  // closing the driver  driver.quit();  } }  

Комментарии:

1. Вы хотите прикрепить изображение в случае сбоя теста. Это правильно? Если да, то почему вы хотите это сделать, потому что это увеличивает размер вашего excel и может привести к проблемам с производительностью.

2. @NandanA Да, я хочу прикрепить снимок экрана, когда тестовый случай завершится неудачно. Я хочу это сделать, потому что это требование. Несмотря на то, что я осознаю тот факт, что это увеличит размер excel.

3. Отправил ответ. Я хотел бы услышать от вас обратную связь.

Ответ №1:

Вы можете сделать это, преобразовав изображение в byte[] затем нарисовать изображение в нужном месте. Ты можешь сделать вот так,

В твоем OTMGeneral классе:

 if (!helloCustomer) {  //Your code } else {  excelUtils.setCellValue(i, 2, "Fail", excelFilePath);  System.out.println("login fail");  // capture screenshot when a test case fails  excelUtils.attachImageToExcel("NameOfScreenshot", i, 3, 0.3); }  

Держите метод attachImageToExcel в своем ExcelUtils . Вам нужно пройти нижеуказанное @Params .

 @Param screenShot - The name what you assigned to the image while capturing. @Param column - Column number @Param row - Row number @Param image size - Pass the float value. Example 0.3 = 30% image  

Код:

 public static void attachImageToExcel(String screenShot, int column, int row, double imageSize)  throws Exception {   Workbook wb = new XSSFWorkbook(new FileInputStream(new File("FileLocation")));  Sheet sheet = wb.getSheet("SheetName");   InputStream inputStream = new FileInputStream("./Screenshots/"   screenShot   ".jpg");  byte[] bytes = IOUtils.toByteArray(inputStream);  int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);  inputStream.close();   CreationHelper helper = wb.getCreationHelper();  Drawing drawing = sheet.createDrawingPatriarch();   ClientAnchor anchor = helper.createClientAnchor();  anchor.setCol1(column);  anchor.setRow1(row);   Picture pict = drawing.createPicture(anchor, pictureIdx);  pict.resize(imageSize);   FileOutputStream fileOut = null;  fileOut = new FileOutputStream((new File("FileLocation")));  wb.write(fileOut);  fileOut.close(); }  

Выход:

введите описание изображения здесь

Комментарии:

1. Вам также нужно добавить расположение файла внутри attachImageToExcel

2. Спасибо вам за усилия, которые вы приложили для решения моей проблемы. Однако предложенное вами решение не работает в моей текущей программе. Вы замечательный человек, и я ценю то время и знания, которые вы потратили, чтобы ответить на этот вопрос.

3. Добро пожаловать.. предложенное вами решение не работает в моей текущей программе. В чем проблема? Если это приведет к некоторым ошибкам, пожалуйста, дайте мне знать, что я могу вам помочь.

4. В моем коде у меня есть вызываемый метод setCellValue() . Этот метод имеет четыре аргумента int rowNum , int cellNum , String cellValue , и String excelFilePath соответственно. Я хочу создать такую программу, которая может вписаться в третий аргумент, т. Е. String cellValue . С помощью этой переменной я записываю результаты в свой лист Excel. Я перепробовал множество функций для достижения этой цели, однако ничего не сработало.

5. Есть две основные цели: 1. Перенесите скриншоты в целевую ячейку листа с помощью String cellValue переменной. 2. Сохраняйте скриншоты с динамическими именами, чтобы не каждый второй снимок экрана должен был перезаписывать первый.