Существует ли альтернатива sendKeys для ввода текста

Добрый день,

Прошу помочь новичку со следующей проблемой при использовании webdriver.
На текстовое поле навешана куча js обработчиков, как раз тестирую эти обработчики.
Опытным путем выяснил что sendKeys передает текст по-символьно, т.е. имитирует работу пользователя.
Интересует возможно ли передать текст в поле по методу копи-паста, т.е. сразу весь целиком вставить в необходимое поле?
Для наглядности приведу пример проблемы: js обработчик блокирует внос в текстовое поле подряд два и более символов тире. При попытке ввода текста “лес—там” с помощью метода sendKeys в поле остается текст “лес-там”, т.к. js заблокировал ввод лишних тире. А при ручном копи-пасте данного текста в поле не заносится ничего, а просто кидает уведомление об ошибке с лишними тире - именно к этому варианту и стремлюсь.
Заранее спасибо!

copy-paste ?

Не совсем то, так как мне необходимо передать текст в поле из текста программы, а не копировать его из другого поля. Плюс на странице нет свободных от js обработчиков полей чтобы сделать такой промежуточный этап.

Попробую развить предложение имитации Ctrl-c ctrl-v. Пример на Питоне -

text_to_put_to_clipboard = driver.find_element_by_xpath("//*[@id='username']").text  # получаем текст из контрола

from Tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()  # очищаем буфер
r.clipboard_append(text_to_put_to_clipboard)  # добавляем в буфер полученный текст

driver.find_element_by_xpath("//*[@id='user_input']").send_keys(Keys.CONTROL, 'v') #paste to user input from clipboard

Суть такая, что вам не обязательно “руками” что-то ложить в буффер. С этим прекрасно справляются языковые средства, которые как минимум очень хорошо помещают в буффер строковые данные.

1 лайк

Как-то так было у меня.
Аналог Ctrl+C (т.е. записать значение в буфер)

StringSelection selection = new StringSelection(stringValue);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, selection);

Вставить:

 driver.findElement(By.xpath(xpath)).sendKeys(Keys.CONTROL + "v");
1 лайк

здравствуйте
я делаю так: исползую Selenium Web Driver
в EXCEL прописиваете те дание которые хотите
in keywords

and Data

и конечно в коде надо создать class operation,например:

switch (operation.toUpperCase()) {
	case "SETTEXT":
		// Set text on control
		try {

			driver.findElement(this.getObject(objectName, objectType))
				.clear();
			driver.findElement(this.getObject(objectName, objectType))
				.sendKeys(cellData);
		}

}

таким образом вы можете встовлять любые символы в любые строки,нужно только правилно писать ID

Появился еще один вопрос по данной теме. В написании тестов был использован метод вставки текста в буфер обмена из программы, с последующей вставкой его в текстовое поле в приложении. Проблема возникла при попытке распараллеливания выполнения тестов с помощью Selenium Grid. Насколько я понял текст не попадает в буфер обмена удаленной машины. Есть ли варианты решения данной проблемы?

Да, исполнять код копирования / вставки непосредственно на ремоутной тачке. Для этого вам надо либо написать свой сервлет и внедрять в грид, либо если уже есть какой-то http сервер, развернутый на той тачке, добавить ему соответствующий end-point. Я такое делал через ремоут сикули сервер, ибо в нем уже встроен полноценный REST клиент.

Спасибо за наводку, буду изучать данный инструмент.

Да вам не обязательно его изучать. Тут суть не в инструменте, а в подходе. Подойдет любой легковесный http-сервер. Там это реализовано при помощи Jersey + GrizzlyHttpServer.

Чтобы вы оценили всю простоту, клиентский код:

    public boolean setClipboardText(final String text) {
        int status;
        Response response = null;

        try {
            response = service.path("io")
                    .path("setClipboardText")
                    .queryParam("text", text)
                    .request(MediaType.APPLICATION_JSON)
                    .post(null);

            status = response.getStatus();
        } catch (Exception ignored) {
            status = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
        } finally {
            if (response != null) {
                response.close();
            }
        }

        return status == Response.Status.OK.getStatusCode();
    }

    public String getClipboardText() {
        String text;

        try {
            text = service.path("io")
                    .path("getClipboardText")
                    .request(MediaType.APPLICATION_JSON)
                    .post(null)
                    .readEntity(String.class);
        } catch (Exception ignored) {
            text = "";
        }

        return text;
    }

Сами end-points:

    @POST
    @Path("/setClipboardText")
    public Response setClipboardText(@QueryParam("text") String text) {
        ClipboardUtils.setClipboardText(text);
        return Response.status(Response.Status.OK).build();
    }

    @POST
    @Path("/getClipboardText")
    public Response getClipboardText() {
        return Response.ok(ClipboardUtils.getClipboardText()).build();
    }