如何:使用 Playwright 与滑块交互

问题描述 投票:0回答:3

我所期待的 我正在尝试与基于角度的网页上的滑块 ui 元素进行交互。下面显示的代码不再与有问题的元素交互。就在某一时刻..

更多信息

阅读提到的“空白”问题,这称为“视图跟踪”。我不能 100% 确定这与该问题有关。

我尝试过的

我在与使用 Angular 构建的网页上的滑块交互时遇到问题。通过我目前的解决方案

 async slideToAgree() {
    const { page } = this

    const {
      width: sw,
      height: sh,
      x: sx,
      y: sy
    } = await (await page.$('.slider-controller')).boundingBox();

    const { width: tw, x: tx } = await (
      await page.$('.slider-container')
    ).boundingBox();

    await page.mouse.move(sx + sw / 2, sy + sh / 2);
    await page.mouse.down();
    await page.mouse.move(tx + tw, sy + sh / 2, { steps: 10 });

  }
}

实际发生了什么/结果

剧作家点击屏幕右上角,网页之外的这个奇怪的“额外空白区域”..让我觉得元素的边界框已损坏/未附加到 DOM?

有人可以提供“单击并拖动”或“与滑块交互”的更新实现吗?到目前为止我遇到的一切都不起作用。

playwright uislider browser-automation playwright-typescript
3个回答
5
投票

也许它可以使用滑块的宽度而不是相对于框的视口位置来解决您的问题?我不知道你的滑块是什么样子,所以我对用 Angular 编写的通用滑块进行了测试,它似乎按预期拖动滑块:

import {test} from '@playwright/test'

test('Move slider', async ({ page, context }) => {

    await page.goto('https://material.angular.io/components/slider/examples')
    const sliderTrack = await page.locator('.mdc-slider__track').first()
    const sliderOffsetWidth = await sliderTrack.evaluate(el => {
        return el.getBoundingClientRect().width
    })

    // Using the hover method to place the mouse cursor then moving it to the right
    await sliderTrack.hover({ force: true, position: { x: 0, y: 0 } })
    await page.mouse.down()
    await sliderTrack.hover({ force: true, position: { x: sliderOffsetWidth, y: 0 } })
    await page.mouse.up()

})

0
投票

除了@candre 的精彩回答 如果您需要单击滑块,请使用具有相同参数的

.click()
方法,例如
hover()
:

await sliderTrack.click({ force: true, position: { x: (sliderOffsetWidth / 3), y: 0 } });

0
投票

有几个问题需要考虑:

  1. 移动拇指时,您应该尊重滑块步长(以像素为单位)(我的代码通过逐渐增加移位直到值更改来处理它)
  2. 当您寻找 2 时,滑块可能位于位置 3(必须扫描整个值范围)
// a function to reuse anywhere
async function slideTo(
  page: Page,
  sliderThumb: Locator,
  input: Locator,
  done: (v: number) => boolean,
) {
  await sliderThumb.waitFor({
    timeout: 200,
  });
  await input.waitFor({
    state: 'attached', // don't expect visible, usually that input is hidden
    timeout: 200,
  });

  let thumbMoveBy = await sliderThumb.evaluate((el) => {
    return el.getBoundingClientRect().width;
  });

  let lastValue = parseInt(await input.inputValue(), 10);

  let movedAllTheWayToTheLeft = false;

  const hoverTimeout = 1000;

  while (!done(lastValue)) {
    await sliderThumb.hover({ force: true, position: { x: 0, y: 0 }, timeout: hoverTimeout });
    await page.mouse.down();

    if (!movedAllTheWayToTheLeft) {
      await sliderThumb.hover({
        force: true,
        position: { x: -1000, y: 0 },
        timeout: hoverTimeout,
      });
      movedAllTheWayToTheLeft = true;
    } else {
      await sliderThumb.hover({
        force: true,
        position: { x: thumbMoveBy, y: 0 },
        timeout: hoverTimeout,
      });
    }
    await page.mouse.up();
    const newValue = parseInt(await input.inputValue(), 10);
    if (newValue === lastValue) {
      thumbMoveBy += 5;
    } else {
      lastValue = newValue;
    }
  }
}


// use example
  const sliderTrack = page.locator('...');
  const sliderInput = page.locator('...'); // that hidden one that holds the value
  await slideTo(page, sliderTrack, sliderInput, (v) => v === 2);

© www.soinside.com 2019 - 2024. All rights reserved.