Доступ к данным в буфере обмена удаленной машины при запуске тестов с использованием selenium-webdriver

У меня следующая установка:

Machine 1 - Ubuntu - selenium hub
Machine 2 - Ubuntu - selenium node
Machine 3 - Windows 8.1 - selenium node

Для выполнения тестов я использую RemoteWebDriver и настроил Jenkins CI на концентраторе.

Проблема: проверяемый мной URL-адрес имеет кнопку, при нажатии на которую данные копируются в буфер обмена. Данные не видны конечному пользователю, если они не вставлены. Меня беспокоит то, что при локальном запуске я могу получить данные системного буфера обмена, используя:

strScript = (String) Toolkit.getDefaultToolkit().getSystemClipboard()
        .getData(DataFlavor.stringFlavor);

Но при запуске кода от jenkins на удаленных машинах я не могу получить содержимое и получаю ошибку ниже:

java.awt.HeadlessException: 
No X11 DISPLAY variable was set, but this program performed an operation which requires it.

Понятно, что он пытается получить данные на сервере jenkins, но есть проблема с отображением. Но мое требование - получить данные, которые были сохранены на удаленном компьютере после нажатия кнопки.

Какие-нибудь решения?

Спасибо.


person Vivek Singh    schedule 02.12.2014    source источник
comment
Я столкнулся с той же проблемой, что и ваша. Я выполняю тесты в Linux, а узел находится на компьютере с Windows. Метод буфера обмена не вставляет элемент, который я скопировал на машине Windows. Есть ли какое-то решение?   -  person Vignesh Paramasivam    schedule 19.02.2016


Ответы (1)


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

  • Создайте настраиваемый сервлет узла, который при вызове будет возвращать содержимое буфера обмена.
  • Запустите узел с этим недавно созданным настраиваемым сервлетом.
  • Используйте такую ​​библиотеку, как Talk2Grid, чтобы найти IP-адрес и порт узла, на который был направлен ваш сеанс. .
  • используйте полученный IP-адрес и порт, чтобы вызвать настраиваемый сервлет для получения доступа к буферу обмена.

Пример ниже должен объяснить все это в действии (я использую селен 3.141.59)

Используемые зависимости

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
  <version>3.141.59</version>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-server</artifactId>
  <version>3.141.59</version>
</dependency>
<dependency>
  <groupId>com.rationaleemotions</groupId>
  <artifactId>talk2grid</artifactId>
  <version>1.2.1</version>
</dependency>
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>7.0.0</version>
</dependency>

Пользовательский сервлет выглядит так, как показано ниже

package com.rationaleemotions.servlets;

import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.openqa.selenium.json.Json;

public class ClipboardServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.setStatus(200);
    try {
      String text = Toolkit.getDefaultToolkit().getSystemClipboard()
          .getData(DataFlavor.stringFlavor)
          .toString();
      Map<String, String> map = new HashMap<>();
      map.put("contents", text);
      response.getWriter().append(new Json().toJson(map));
    } catch (UnsupportedFlavorException e) {
      e.printStackTrace();
    }
  }
}

Предположим, что наш сервлет принадлежит банке с именем "servlets.jar". Вот как вы начинаете работу с узлом

java -cp servlets:selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncherV3 -role node -servlets com.rationaleemotions.servlets.ClipboardServlet

Хаб запускается командой

java -jar selenium-server-standalone-3.141.59.jar -role hub

Вот образец, который будет использовать все это.

package com.rationaleemotions;

import com.rationaleemotions.pojos.Host;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class ClipboardSample {

  private RemoteWebDriver driver;

  @BeforeClass
  public void beforeClass() throws MalformedURLException {
    driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"),
        DesiredCapabilities.chrome());
  }

  @Test
  public void demo() throws Exception {
    String text = "Mussum ipsum cacilds, vidis litro abertis. Consetis adipiscings elitis. Pra lá , depois divoltis porris, paradis. Paisis, filhis, espiritis santis. Mé faiz elementum girarzis, nisi eros vermeio, in elementis mé pra quem é amistosis quis leo. Manduma pindureta quium dia nois paga.";
    driver.navigate().to("https://googlechrome.github.io/samples/async-clipboard/");

    driver.findElement(By.cssSelector("textarea#out")).sendKeys(text);
    TimeUnit.SECONDS.sleep(1);
    takeScreenshot();
    driver.findElement(By.cssSelector("button#copy")).click();
    TimeUnit.SECONDS.sleep(1);
    Host grid = new Host("localhost", "4444");
    Host node = new GridApiAssistant(grid)
        .getNodeDetailsForSession(driver.getSessionId().toString());
    String url = String
        .format("http://%s:%d/extra/ClipboardServlet", node.getIpAddress(), node.getPort());
    Request request = new Request.Builder().url(url).build();

    Call call = new OkHttpClient.Builder().build().newCall(request);
    Response response = call.execute();
    String localClipboardData = response.body().string();
    Map<String, String> data = new Json().toType(localClipboardData, Map.class);
    Assert.assertEquals(text, data.get("contents"));
  }

  private void takeScreenshot() throws IOException {
    File src = driver.getScreenshotAs(OutputType.FILE);
    File target = new File(
        System.getProperty("user.dir") + File.separator + "target" + File.separator +
            "screenshot.jpg");
    FileUtils.copyFile(src, target);
  }

  @AfterClass
  public void afterClass() {
    if (driver != null) {
      driver.quit();
    }
  }
}
person Krishnan Mahadevan    schedule 16.12.2019