microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
66.85k stars 3.66k forks source link

[BUG] locator.getAttribute('href') doesn't return the absolute URL #9272

Closed vsravuri closed 3 years ago

vsravuri commented 3 years ago

Context:

Code Snippet Not working with locator.getAttribute('href)

const href = await elementHandle.locator('css=tr > td >> text="' + template + '"').last().getAttribute('href');
console.log(href)

Output: 
newTemplate3.aspx?tid=16

Works without locator

const href = await elementHandle.$eval('css=tr > td >> text=' + template, el => el.href);
console.log(href)

Output: 
<hostname>/Template/newTemplate3.aspx?tid=16

Describe the bug locator.getAttribute('href) doesn't return the absolute URL, returns the relative path

Screen_Shot_2021-10-01_at_5_13_53_PM

pavelfeldman commented 3 years ago

https://www.google.com/amp/s/www.geeksforgeeks.org/what-is-the-difference-between-properties-and-attributes-in-html/amp/

await locator.evaluate(e => e.href);

will give you the property.

vsravuri commented 3 years ago

Thanks @pavelfeldman for helping me understand how this works. I tried your suggestion, it works. It will be helpful if a note is added in Playwright documentation 'locator.getAttribute will not return the modified value after page has been loaded.'

I migrated my code from Protractor

element(by.tagName('a')).getAttribute('href');

Here i get the absolute URL, also the Protractor documentation says this

Schedules a command to query for the value of the given attribute of the element. Will return the current value, even if it has been modified after the page has been loaded.

https://www.protractortest.org/#/api?view=webdriver.WebElement.prototype.getAttribute

I expected the behavior is similar in Playwright.

Please feel free to close this ticket.

pavelfeldman commented 3 years ago

This is not about the modifications, Playwright also returns the current (new) value if it has been modified. It is about the fact that element.href and element.getAttribute('href') have nothing to do with each other, one is attribute, another is property. Different things with different values as explained in the article I shared.

PrDagi commented 9 months ago

pass the link selector as argument to the evaluate method 

const linkTag = await elementHandle.locator('css=tr > td >> text="' + template + '"').last();
let href = await page.evaluate( (linkTag) => linkTag.href)
console.log(href)