15

I have input text field on the page with id "email30" and I am trying to read it's value from Playwright

  let dd_handle = await page.$("#email30");
  let value = await dd_handle.getAttribute("value");

However it come back "" although I have a value inside the input text. When I inspect I don't see the value attribute is set to a current value either.

Normal JS code as following gives me correct value

document.getElementById("email30").value

Not sure how I can read value from the playwright framework. Can any one please advise? Their documents are quite not helpful here.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Paresh Varde
  • 1,084
  • 3
  • 16
  • 39

4 Answers4

23

There are three major trends how to retrieve input values with playwright/puppeteer.

page.evaluate

const value = await page.evaluate(el => el.value, await page.$('input'))

page.$eval

const value = await page.$eval('input', el => el.value)

page.evaluate with Element.getAttribute

const value = await page.evaluate(() => document.querySelector('input').getAttribute('value'))

The first two will return the same result with very similar performance, I can't bring up an example when we could favor one over the other (maybe one: the one with $eval is shorter). The third one with Element.getAttribute is not advised if you are manipulating an input's value before evaluation and you want to retrieve the new value. It will always return the original attribute value, which is an empty string in most of the cases. It is a topic of attribute vs property value in JavaScript.

However page.evaluate with Element.getAttribute can be handy when you need such attributes that can't be accessed with the other mentioned methods (e.g.: class names, data attributes, aria attributes etc.)

theDavidBarton
  • 7,643
  • 4
  • 24
  • 51
8

Ok finally following code did the job for me!

const value = await page.$eval("#email30", (el) => el.value);
Paresh Varde
  • 1,084
  • 3
  • 16
  • 39
2

This works the best so far

const somevalue = this.page.inputValue('#Name');
QA Fortify
  • 41
  • 2
  • 6
  • 3
    Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Dec 07 '21 at 21:29
-1

Playwright prefers locators over Puppeteer-style $ and eval methods. With locator, you can use inputValue to get the current input value for one or more elements.

You can also call page.inputValue(selector) directly to get the input value of the first matching selector, but that's now discouraged in favor of the locator approach.

Here's a couple of minimal, complete examples:

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

let browser;
(async () => {
  browser = await playwright.chromium.launch();
  const page = await browser.newPage();
  await page.setContent(`<input value="foo">`);

  console.log(await page.inputValue("input")); // => foo

  const input = page.locator("input");
  await input.fill("bar");
  console.log(await input.inputValue()); // => bar
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

If you have multiple elements:

const playwright = require("playwright");

const html = `<input value="foo"><input value="bar">`;

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

  console.log(await page.inputValue("input")); // => foo

  const loc = page.locator("input");
  await loc.nth(1).fill("baz");

  // iterate all:
  for (const el of await loc.all()) {
    console.log(await el.inputValue());
  }

  // or make an array (option 1):
  const values1 = await Promise.all(
    [...await loc.all()].map(e => e.inputValue())
  );
  console.log(values1); // => [ 'foo', 'baz' ]

  // or make an array (option 2):
  const values2 = await loc.evaluateAll(els  => els.map(el => el.value));
  console.log(values2); // => [ 'foo', 'baz' ]
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());
ggorlen
  • 44,755
  • 7
  • 76
  • 106