Playwright: [Feature]: Ability to check wait for value on a input

Created on 20 Mar 2020  路  11Comments  路  Source: microsoft/playwright

It would be great if Playwright had something similar to CodeceptJS methods:
image
or

image

I guess this could be in a form similar to waitForProperty? which waits for an element to exist and waits for a property of key and value

e.g. waitForProperty(selector, "innerText", "Foo",{timeout}) waitForProperty(selector, "value", "bar",{timeout})

Most helpful comment

Thanks for the suggestion! I wonder if you were able to use waitForSelector with a text selector? For example, the following would wait for an element with text Foo.

page.waitForSelector('text=Foo')

It is possible to have a narrower criteria, like wait for a div with the same text.

page.waitForSelector('css=div >> text=Foo')

I'm trying to learn if there are reasons this wouldn't work for your needs?

All 11 comments

Thanks for the suggestion! I wonder if you were able to use waitForSelector with a text selector? For example, the following would wait for an element with text Foo.

page.waitForSelector('text=Foo')

It is possible to have a narrower criteria, like wait for a div with the same text.

page.waitForSelector('css=div >> text=Foo')

I'm trying to learn if there are reasons this wouldn't work for your needs?

Thanks for the response this >> text=Foo is this some playwright specific thing for the css engine? Can't see to get it work for my custom locator. I should have clarified i'm using a custom locator engine e.g.

The problem area i'm working in is shadow dom, im using the awesome custom selectors feature to register a selector, like so: https://github.com/Georgegriff/query-selector-shadow-dom#playwright

await page.goto('chrome://downloads');
  // shadow= allows a css query selector that automatically pierces shadow roots.
  await page.waitForSelector('shadow=#no-downloads span', {timeout: 3000})

Yes, the >> combinator is part of the selector syntax and can be used to combine multiple selectors (in the above case, css=div and text=Foo). Can you share more details on what is not working?

Also we fixed an issue in #1169, and it might be worth trying against playwright@next

Thanks for the info, i'll experiment and get back to you

So i took a look, this is mostly fantastic for text. Where it runs into problems is value on input fields.
Typically the property value of inputs are set using a js property but not reflected to an attribute so css/xpath selectors wont work. I'm wondering if it might be possible to expose some more helpers similar to the text=* for value properties

Typically the property value of inputs are set using a js property but not reflected to an attribute so css/xpath selectors wont work.

Can you elaborate on this please? If the value is an attribute on the element, one can use input[value="placeholder"], but it seems that not the case? What could be a helper that would fix this?

Value on input is not always an attribute in the HTML. Forgive me i'm stating something you're already aware of but.
In the DOM you have attributes (the stuff you can see in the dom e.g. href, src etc)

But dom elements also have properties these are not available in the html, but sometimes properties are reflected to attributes such that they have the same value.

For input elements the value property is not automatically reflected. For example

values_input

Hopefully the gif shows how attributes in the dom aren't always reflected to their properties and vice versa. If i do a setAttribute on value it does nothing, if i do a .value updates in the UI but does not update the getAttribute call

And because the attribute value is not updated when the property is set a css/xpath selector on that attribute doesnt do anything

I can do this in user land with a custom engine by copying what your code does for these, but might be trickier https://github.com/microsoft/playwright/blob/9826fd652ef76967dd5cfc358dab91e26b008f36/src/injected/injected.ts#L24 bu for properties in instead

Related issue someone else asking for this: https://github.com/microsoft/playwright/issues/1427

For reference he's a naive implementation, doesn't work as well as text built in engine because it relies on a previous compound selector to have found an element for it to succeed.

const createValueEngine = () => {
  return {
    // Creates a selector that matches given target when queried at the root.
    // Can return undefined if unable to create one.
    create(root, target) {
      return null;
    },

    // Returns the first element matching given selector in the root's subtree.
    query(root, selector) {
      if (!root) {
        return null;
      }
      return "" + root["value"] === selector;
    },

    // Returns all elements matching given selector in the root's subtree.
    queryAll(root, selector) {
      if (!root) {
        return null;
      }
      return "" + root["value"] === selector;
    }
  };
};
await playwright.selectors.register("value", createValueEngine);

// example usage input.my-cvlass >> value="User input value"

Thanks @georgegriff! I think #1427 captures this issue, and I'm going to close this as a duplicate for now. Feel free to reopen if I've missed something.

Was this page helpful?
0 / 5 - 0 ratings