#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. Сохраняйте скриншоты с динамическими именами, чтобы не каждый второй снимок экрана должен был перезаписывать первый.