Rayrun
← Back to Discord Forum

Migrating from Selenium to Playwright

Hi guys, we are migrating our test framework from the Selenium to the Playwright and I had run into a problem. We are using the strategy pattern to run our automation tests until everything will be rewritten to the Playwright engine. And I have the following code which executes the JS code.

This is the common code for Selenium and for the Playwright

./some-POM-file.cs

public static void ScrollIntoViewIfNeeded(IControlAdapter element)
        {Browser.JavaScriptExecutor.ExecuteScript("arguments[0].scrollIntoViewIfNeeded();", element);
        }

./Browser.cs

public static IJSExecutor JavaScriptExecutor => _browserStrategy.JavaScriptExecutor;

./PlaywrightJSExecutor

private object EvaluateJavaScript(string jsScript, IControlAdapter control = null)
        {
            var evaluatedScript = PreEvaluating(jsScript);

            return _page.EvaluateAsync(evaluatedScript, new object[] { control.ToLocator() }).GetAwaiter().GetResult().Value.ToString();
        }

        private string PreEvaluating(string jsScript) => jsScript.Replace("return ", string.Empty);

        public object ExecuteScript(string script, IControlAdapter control = null)
        {
            return EvaluateJavaScript(script, control);
        }

./Extensions.cs

public static ILocator ToLocator(this IControlAdapter controlAdapter)
        {
            if (controlAdapter is not null)
            {
                if (controlAdapter is LocatorAdapter locatorAdapter)
                {
                    return locatorAdapter?.GetControlInstance();
                }
                else
                {
                    throw new Exception($"The {controlAdapter?.GetType().Name} is not applicable to {typeof(ILocator)}.");
                }
            }

            return null;
        }

This thread is trying to answer question "How to resolve the 'ReferenceError: arguments is not defined' error when migrating from Selenium to Playwright?"

3 replies

so, when I try to pass this JS script arguments[0].scrollIntoViewIfNeeded(); and cast element to ILocator with ToLocator() extension method, I got the next error:

Microsoft.Playwright.PlaywrightException : ReferenceError: arguments is not defined
        at eval (eval at evaluate (:201:30), <anonymous>:1:1)
        at eval (<anonymous>)
        at UtilityScript.evaluate (<anonymous>:201:30)
        at UtilityScript.<anonymous> (<anonymous>:1:44)

Any ideas guys? Thank u

this is the answer

var arguments = new[] { control };
var script = "return arguments[0].scrollIntoViewIfNeeded();"
await page.EvaluateAsync($"(arguments) => \{ {script} \}", arguments );

If control is a Locator object, you can also do either just: await control.ScrollIntoViewIfNeededAsync(); or await control.EvaluateAsync("control => control.scrollIntoViewIfNeeded()");

Related Discord Threads

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.