Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ExecuteScriptAsync visible from WebviewBridge #28

Open
TamaBaka opened this issue Jun 23, 2022 · 1 comment
Open

Make ExecuteScriptAsync visible from WebviewBridge #28

TamaBaka opened this issue Jun 23, 2022 · 1 comment

Comments

@TamaBaka
Copy link

TamaBaka commented Jun 23, 2022

There is an interesting segment of code in SpiderEye.Bridge.WebviewBridge:

        public async Task InvokeAsync(string id, object data)
        {
            string script = GetInvokeScript(id, data);
            string? resultJson = await Application.Invoke(() => Webview.ExecuteScriptAsync(script));
            ResolveEventResult(id, resultJson);
        }

I'm actually using webview for automation instead of creating an interactable custom webpage so I found the ExecuteScriptAsync feature useful on the Windows Webview. Except I was trying to port my code to a Raspberry Pi and Webview currently doesn't work on Linux.

Given the code segment above, I think it might be possible to reproduce that behavior here if we could directly inject a custom javascript string instead of searching for a pre-registered function. I.e. skip the GetInvokeScript step and the ResolveEventResult step and just return resultJson directly.

Is this not done because the intent of the bridge was to work with well-defined endpoints? Or is it because calling ExecuteScriptAsync directly is inherently unstable and creates all sorts of unpredictable side effects? Did I happen to miss a function that actually does what I'm requesting already?

Bear in mind that I don't control the endpoint, so I can't insert custom code into the destination webpage. And I'm not desperate enough to encapsulate the endpoint into an iFrame just so I can embed tools in the parent container to manipulate whatever's in the iFrame.

That being said, here's an example of my code when I directly used Webview2.

                        var script = $@"
                                document.querySelector(""input[name='USER']"").value = ""{ kvp[0] }"";
                                document.querySelector(""input[name='PASSWORD']"").value = ""{ kvp[1] }"";
                                document.querySelector(""#logon_button"").click();
                        ";

                        await signInView.ExecuteScriptAsync(script);

Set a user, set a password, then click a specific button. Wait for page loaded event to execute further actions.

@TamaBaka
Copy link
Author

TamaBaka commented Jun 24, 2022

Oh neat, it worked. Just need to clone the code, add the following to WebviewBridge

        public async Task<string?> ExecuteScriptAsync(string script)
        {
            return await Application.Invoke(() => Webview.ExecuteScriptAsync(script));
        }

Then add a definition to IWebviewBridge

Task<string?> ExecuteScriptAsync(string script);

Recompile and use the updated SpiderEye.Core library and now you can use window.Bridge.ExecuteScriptAsync

Tested the below simple case on Windows and Linux.

               window.LoadUrl("https://www.google.com");
              
              window.EnableDevTools = true;
              
                var stage = "1";        // simple state machine to prevent an infinite pageloaded event loop

                window.PageLoaded += async (s, e) =>
                {
                    if (stage == "1")
                        await window.Bridge.ExecuteScriptAsync($@"
                            console.log(""Hello World"");
                            document.querySelectorAll('input[title=""Search""]')[0].value = ""Hello World"";
                            document.querySelectorAll('input[value=""Google Search""]')[0].click();");

                    stage = "2";

                };

Stability of this change is unknown but it works on the simple stuff.

First time I've ever had to create a nullable string though. That's just weird when string is nullable already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant