Перейти к основному содержимому

Handles

Введение

Playwright может создавать ссылки на элементы DOM страницы или любые другие объекты внутри страницы. Эти ссылки существуют в процессе Playwright, тогда как реальные объекты находятся в браузере. Существует два типа ссылок:

  • JSHandle для ссылки на любые JavaScript объекты на странице
  • ElementHandle для ссылки на DOM элементы на странице, он имеет дополнительные методы, которые позволяют выполнять действия с элементами и проверять их свойства.

Поскольку любой DOM элемент на странице также является JavaScript объектом, любой ElementHandle также является JSHandle.

Ссылки используются для выполнения операций с этими реальными объектами на странице. Вы можете выполнять вычисления на ссылке, получать свойства ссылки, передавать ссылку в качестве параметра вычисления, сериализовать объект страницы в JSON и т.д. См. API класса JSHandle для этих и других методов.

Справочник API

Вот самый простой способ получить JSHandle.

JSHandle jsHandle = page.evaluateHandle("window");
// Используйте jsHandle для вычислений.

Ссылки на элементы

Не рекомендуется

Использование ElementHandle не рекомендуется, используйте объекты Locator и утверждения, ориентированные на веб, вместо этого.

Когда требуется ElementHandle, рекомендуется получать его с помощью методов Page.waitForSelector() или Frame.waitForSelector(). Эти API ожидают, пока элемент не будет прикреплен и видим.

// Получите ссылку на элемент
JSHandle jsHandle = page.waitForSelector("#box");
ElementHandle elementHandle = jsHandle.asElement();

// Проверьте ограничивающий прямоугольник элемента
BoundingBox boundingBox = elementHandle.boundingBox();
assertEquals(100, boundingBox.width);

// Проверьте атрибут элемента
String classNames = elementHandle.getAttribute("class");
assertTrue(classNames.contains("highlighted"));

Ссылки в качестве параметров

Ссылки могут быть переданы в методы Page.evaluate() и аналогичные. Следующий фрагмент создает новый массив на странице, инициализирует его данными и возвращает ссылку на этот массив в Playwright. Затем он использует ссылку в последующих вычислениях:

// Создайте новый массив на странице.
JSHandle myArrayHandle = page.evaluateHandle("() => {\n" +
" window.myArray = [1];\n" +
" return myArray;\n" +
"}");

// Получите длину массива.
int length = (int) page.evaluate("a => a.length", myArrayHandle);

// Добавьте еще один элемент в массив, используя ссылку
Map<String, Object> arg = new HashMap<>();
arg.put("myArray", myArrayHandle);
arg.put("newElement", 2);
page.evaluate("arg => arg.myArray.add(arg.newElement)", arg);

// Освободите объект, когда он больше не нужен.
myArrayHandle.dispose();

Жизненный цикл ссылок

Ссылки могут быть получены с помощью методов страницы, таких как Page.evaluateHandle(), Page.querySelector() или Page.querySelectorAll() или их аналогов для фреймов Frame.evaluateHandle(), Frame.querySelector() или Frame.querySelectorAll(). После создания ссылки будут удерживать объект от сборки мусора, если только страница не навигируется или ссылка не удаляется вручную с помощью метода JSHandle.dispose().

Справочник API

Локатор против ElementHandle

предупреждение

Мы рекомендуем использовать ElementHandle только в редких случаях, когда вам нужно выполнить обширный обход DOM на статической странице. Для всех пользовательских действий и утверждений используйте локатор.

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

В примере ниже, ссылка указывает на конкретный DOM элемент на странице. Если этот элемент изменяет текст или используется React для рендеринга совершенно другого компонента, ссылка все равно указывает на этот устаревший DOM элемент. Это может привести к неожиданным поведениям.

ElementHandle handle = page.querySelector("text=Submit");
handle.hover();
handle.click();

С локатором, каждый раз, когда используется локатор, актуальный DOM элемент находится на странице с использованием селектора. Таким образом, в приведенном ниже фрагменте, подлежащий DOM элемент будет найден дважды.

Locator locator = page.getByText("Submit");
locator.hover();
locator.click();