MaylorTaylor
MaylorTaylor

Reputation: 5041

Get injected javascript from a website when testing with Selenium / Protractor

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

Answers (1)

Sergey Pleshakov
Sergey Pleshakov

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

Related Questions