觸控事件(舊版)
簡介
處理舊版 觸控事件 以回應滑動、縮放和點擊等手勢的網頁應用程式,可以透過手動分派 TouchEvent 到頁面來進行測試。以下範例說明如何使用 Locator.dispatchEvent()
並將 Touch 點作為引數傳遞。
請注意,Locator.dispatchEvent()
不會設定 Event.isTrusted
屬性。如果您的網頁依賴此屬性,請確保在測試期間停用 isTrusted
檢查。
模擬平移手勢
在以下範例中,我們模擬預期會移動地圖的平移手勢。受測試的應用程式只使用觸控點的 clientX/clientY
座標,因此我們只初始化這些項目。在更複雜的情況下,如果您的應用程式需要的話,您可能還需要設定 pageX/pageY/screenX/screenY
。
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.*;
public class TouchEvents {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch();
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setViewportSize(412, 839)
.setDeviceScaleFactor(2.625)
.setUserAgent("Mozilla/5.0 (Linux; Android 12; Pixel 7 Build/SP1A.210812.015) AppleWebKit/537.36" +
" (KHTML, like Gecko) Chrome/94.0.4606.71 Mobile Safari/537.36")
.setHasTouch(true)
.setIsMobile(true)
);
Page page = context.newPage();
page.navigate("https://www.google.com/maps/place/@37.4117722,-122.0713234,15z", new Page.NavigateOptions().setWaitUntil(WaitUntilState.COMMIT));
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Keep using web")).click();
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Keep using web")).waitFor(
new Locator.WaitForOptions().setState(WaitForSelectorState.HIDDEN));
Locator met = page.locator("[data-test-id='met']");
for (int i = 0; i < 5; i++) {
pan(met, 200, 100);
}
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("screenshot.png")));
}
}
public static void pan(Locator locator, int deltaX, int deltaY) {
pan(locator, deltaX, deltaY, 5);
}
public static void pan(Locator locator, int deltaX, int deltaY, int steps) {
BoundingBox bounds = locator.boundingBox();
double centerX = bounds.x + bounds.width / 2;
double centerY = bounds.y + bounds.height / 2;
List<Map<String, Object>> touches = List.of(Map.of(
"identifier", 0,
"clientX", centerX,
"clientY", centerY
));
locator.dispatchEvent("touchstart", Map.of(
"touches", touches,
"changedTouches", touches,
"targetTouches", touches
));
for (int i = 1; i <= steps; i++) {
touches = List.of(Map.of(
"identifier", 0,
"clientX", centerX + deltaX * i / steps,
"clientY", centerY + deltaY * i / steps
));
locator.dispatchEvent("touchmove", Map.of(
"touches", touches,
"changedTouches", touches,
"targetTouches", touches
));
}
locator.dispatchEvent("touchend");
}
}
模擬縮放手勢
在以下範例中,我們模擬縮放手勢,也就是兩個觸控點彼此靠近的動作。這預期會縮小地圖。受測試的應用程式只使用觸控點的 clientX/clientY
座標,因此我們只初始化這些項目。在更複雜的情況下,如果您的應用程式需要的話,您可能還需要設定 pageX/pageY/screenX/screenY
。
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.*;
public class TouchEvents {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch();
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setViewportSize(412, 839)
.setDeviceScaleFactor(2.625)
.setUserAgent("Mozilla/5.0 (Linux; Android 12; Pixel 7 Build/SP1A.210812.015) AppleWebKit/537.36" +
" (KHTML, like Gecko) Chrome/94.0.4606.71 Mobile Safari/537.36")
.setHasTouch(true)
.setIsMobile(true)
);
Page page = context.newPage();
page.navigate("https://www.google.com/maps/place/@37.4117722,-122.0713234,15z", new Page.NavigateOptions().setWaitUntil(WaitUntilState.COMMIT));
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Keep using web")).click();
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Keep using web")).waitFor(
new Locator.WaitForOptions().setState(WaitForSelectorState.HIDDEN));
Locator met = page.locator("[data-test-id='met']");
for (int i = 0; i < 5; i++) {
pinch(met, 40, "in");
}
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("screenshot.png")));
}
}
public static void pinch(Locator locator, int deltaX, String direction) {
pinch(locator, deltaX, direction, 5);
}
public static void pinch(Locator locator, int deltaX, String direction, int steps) {
BoundingBox bounds = locator.boundingBox();
double centerX = bounds.x + bounds.width / 2;
double centerY = bounds.y + bounds.height / 2;
double stepDeltaX = deltaX / (steps + 1.0);
List<Map<String, Object>> touches = List.of(
Map.of("identifier", 0, "clientX", centerX - (direction.equals("in") ? deltaX : stepDeltaX), "clientY", centerY),
Map.of("identifier", 1, "clientX", centerX + (direction.equals("in") ? deltaX : stepDeltaX), "clientY", centerY)
);
locator.dispatchEvent("touchstart", Map.of("touches", touches, "changedTouches", touches, "targetTouches", touches));
for (int i = 1; i <= steps; i++) {
double offset = direction.equals("in") ? (deltaX - i * stepDeltaX) : (stepDeltaX * (i + 1));
touches = List.of(
Map.of("identifier", 0, "clientX", centerX - offset, "clientY", centerY),
Map.of("identifier", 1, "clientX", centerX + offset, "clientY", centerY)
);
locator.dispatchEvent("touchmove", Map.of("touches", touches, "changedTouches", touches, "targetTouches", touches));
}
locator.dispatchEvent("touchend", Map.of("touches", List.of(), "changedTouches", List.of(), "targetTouches", List.of()));
}
}