Search code examples
angularjstypescriptprotractorplaywrightplaywright-test

Access AngularJS's scope in Playwright (migration from protractor)?


i'm facing a small (i hope) issue, for personal purpose i need to migrate from protractor to playwright, i add a lot of steps working well without any issues, but now i'm stuck, the migrate protactor's code using executeScript() and accessign scope.

Here is what i had in Protractor :

browser.executeScript(element => $(element).scope().$ctrl.myFunction(), finder.getWebElement());

in Playwright i tried that (with console.log to for debugging) :

const elementHandle: ElementHandle | null = await this.button.elementHandle();

await this.page.evaluate(
({ element, functionName }) => {
                    const angularElement = (window as any).angular.element(element);
                    const scope = angularElement.scope();
                    console.log("📣📣📣", scope); // returns undefined
                    console.log("📣📣📣",scope.$ctrl); // returns also undefined of course
                    scope.$ctrl[myFunction]();
                },
                { element: elementHandle, functionName }
            );

i'm completely lost, i don't see how can i achieve this, thanks in advance for your help !


Solution

  • Finally found out !

    In Angular to access scope you're apparently need to be in debug mode, so In case of using Playwright I've just created a method to do it and called it in the Cucumber's "Before" Hook :

    async enableDebugMode() {
            // Create a promise that will resolve when the page reloads
            const pageReloaded = new Promise((resolve) => {
                this.mainWindow.once("load", resolve);
            });
    
            // Check if AngularJS is loaded before enabling the debug mode
            await this.mainWindow.evaluate(() => {
                if ((window as any).angular) {
                    (window as any).angular.reloadWithDebugInfo();
                }
            });
    
            // Wait for the page to fully load
            await pageReloaded;
    
            // Check if debug mode is enabled
            const isDebugModeEnabled = await this.mainWindow.evaluate(() => {
                const bodyClasses = document.body.className.split(" ");
                return bodyClasses.includes("ng-scope");
            });
    
            // Added that for debugging purposes
            console.log("Is Debug Mode Enabled:", isDebugModeEnabled);
        }