How to read a textbox value from a playwright

Viewed 14067

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.

4 Answers

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.)

Ok finally following code did the job for me!

const value = await page.$eval("#email30", (el) => el.value);

This works the best so far

const somevalue = this.page.inputValue('#Name');

To add to this excellent answer, with locator, you can use inputValue to get the current input value for one or more elements, or call page.inputValue(selector) directly to get the input value of the first matching selector.

Here's a couple of minimal, complete examples:

const playwright = require("playwright");

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 = await page.locator("input");

  await page.fill("input", "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 els = await page.locator("input");
  await els.nth(1).fill("baz");
  console.log(await els.first().inputValue()); // => foo
  console.log(await els.nth(0).inputValue()); // => foo
  console.log(await els.last().inputValue()); // => baz

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

  // or make an array:
  const content = await Promise.all(
    [...await els.elementHandles()].map(e => e.inputValue())
  );
  console.log(content);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close())
;
Related