Получить массив имен классов для элемента Playwright

Каков наиболее эффективный способ получить массив всех имен классов для элемента в Playwright с помощью TypeScript?

Я не могу найти какой-либо API для этой очень типичной задачи, и мне пришлось написать следующее:

export const getClassNames = async (locator: Locator): Promise<string[]> => {
    // Make sure that we exctly one element
    await expect(locator).toHaveCount(1);

    // Get the element
    const element = locator.first();

    // Use evaluateHandle to get an array of class names for the element
    const classListHandle = await element.evaluateHandle((el: Element) => Array.from(el.classList));

    // Get the result from the classListHandle
    const classNames = await classListHandle.jsonValue() as string[];

    return classNames;
};

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

Vishal Aggarwal 17.04.2023 11:23

Это поможет вам быстрее получать ответы.

Vishal Aggarwal 17.04.2023 11:26

Я добавил свою пользовательскую функцию, но на самом деле я хотел спросить, действительно ли в самом Playwright нет существующего API?

doberkofler 17.04.2023 12:02
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
3
99
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вы проверяете классы элементов, аккуратно:

const locator = page.locator('list > .component');
await expect(locator).toHaveClass(['component', 'component selected', 'component']);

Вы также можете использовать регулярное выражение в этом:

await expect(locator).toHaveClass(/selected/);

Ссылка: https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-class

Ответ принят как подходящий

На момент написания такой функции не было, но вы можете значительно сократить свой код:

export const getClassNames = (locator: Locator): Promise<string[]> =>
  locator.evaluate(el => [...el.classList]);

Если вы работаете в строгом режиме, .evaluate уже утверждает, что есть один элемент, и нет необходимости в промежуточных ElementHandles, которые Драматург обычно не рекомендует использовать.

Вот работающее доказательство концепции:

const playwright = require("playwright"); // 1.30.0

const classList = loc => loc.evaluate(el => [...el.classList]);

let browser;
(async () => {
  browser = await playwright.chromium.launch();
  const page = await browser.newPage();

  await page.setContent(`<p class = "a b c"></p>`);
  console.info(await classList(page.locator("p"))); // => [ 'a', 'b', 'c' ]

  await page.setContent(`<p></p><p></p>`);
  console.info(await classList(page.locator("p")));
    // => strict mode violation: locator('p') resolved to 2 elements
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

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

await expect(locator).toHaveClass(["some", "classes"]);

как описано в этом ответе вместо этого.

Я бы надеялся, что у Playwright уже есть что-то подобное, поскольку DOM уже предоставляет стандартизированный способ доступа к classList.

doberkofler 18.04.2023 16:13

У Playwright нет макросов для каждого свойства DOM, только некоторые из наиболее распространенных. Я думаю, это хорошо — API уже довольно раздут по сравнению с Puppeteer.

ggorlen 18.04.2023 16:40

Другие вопросы по теме