Reputation: 5041
I'm using Selenium / Protractor to test my application's UI and html. I have a that is injected into the sites and I want to grab the contents of this script tag so I can use it for some tests.
An example of the script is below:
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "LocalBusiness",
"name": "The Best Company Name",
"image": "https://www.urltowebsite.us/WebContent/Images/Dealer/6/Logo.png?preset=Dealer.Logo",
"address": {
"@type": "PostalAddress",
"streetAddress": "19 North Suite 2 ",
"addressLocality": "Mobile",
"addressRegion": "MS",
"postalCode": "39107",
"addressCountry": "USA"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": "32.351923",
"longitude": "-88.73434"
},
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": [
"Monday"
],
"opens": "07:30:00",
"closes": "17:00:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": [
"Tuesday"
],
"opens": "07:30:00",
"closes": "17:00:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": [
"Wednesday"
],
"opens": "07:30:00",
"closes": "12:00:00"
}
]
}
</script>
I tried this method below, which seemed to work some of the time but other times I would just get NULL. Possibly due to timing issues?
// site.po.ts (po == page object)
export class Site {
async getLDJson() {
const ldJsonScript = await browser.element(by.xpath(
'//script[@type="application/ld+json"]'
)).getAttribute('innerHTML');
const parsedLdJson = JSON.parse(ldJsonScript);
return parsedLdJson;
}
}
And I would call it before my tests so I could guarantee I had the info
// dealership.test.ts
describe('Dealership Site', () => {
const site: Site = new Site();
const cu: ContactUsPage = new ContactUsPage();
beforeAll(async () => {
await cu.goToDealership();
browser.sleep(3000);
await site.getLDJson();
});
});
//contact_us.po.ts
async goToDealership(dealerName: string = 'wilsonsaw', nextPage: string = "") {
await browser.waitForAngularEnabled(false);
var url = this.composeUrl(dealerName);
const currentUrl = await browser.getCurrentUrl();
url = `${url}${nextPage}`;
if (url !== currentUrl) {
await browser.navigate().to(url);
}
}
Upvotes: 0
Views: 172
Reputation: 8978
browser.sleep(3000);
needs await
to wait until it's done
* waitUntilElementHasAttribute
* @param {ElementFinder} $element Locator of element
* @param {String} attributeName Attribute of an element to evaluate
* @param {number} [timeout=timeouts.ms1000] Time in ms (med. is 1000ms)
* @return {Promise}
*/
let waitUntilAttributeIsntNull = ($element, attributeName, timeout = 1000) => {
return browser.wait(
() => $element.getAttribute(attributeName).then(attributeValue => {
return attributeValue !== null
}),
timeout,
'Wait until element \'' + $element.locator() + '\' is not null',
);
}
// usage
await waitUntilAttributeIsntNull(
element(by.xpath('//script[@type="application/ld+json"]')),
'innerHTML',
3000
)
The only thing that may still go wrong, is the function will fail if element is not yet present. I'd recommend to just add regular wait for presence
and then use this function
Upvotes: 1