AngleSharp / AngleSharp.Js

:angel: Extends AngleSharp with a .NET-based JavaScript engine.
https://anglesharp.github.io
MIT License
103 stars 22 forks source link

Accessing Document.ReadyState in JavaScript exposes enum value instead of string #86

Closed Sebbs128 closed 6 months ago

Sebbs128 commented 1 year ago

Bug Report

Prerequisites

For more information, see the CONTRIBUTING guide.

Description

Creating this as the AngleSharp.Js counterpart to https://github.com/AngleSharp/AngleSharp/issues/1109

When JavaScript in a HTML document reads the document.readyState property, the value returned is a digit (the underlying value of the DocumentReadyState enum) instead of the expected string (such as "loading" or "complete").

Steps to Reproduce

Reproduction using Top Level Statements

using AngleSharp;
using AngleSharp.Js;

string html = """
            <html>
                <head>
                    <script type="text/javascript">
                        document.onreadystatechange = function() {
                            console.log("Document OnReadyStateChange fired");
                            console.log(document.readyState);

                            if (document.readyState == "complete")
                                console.log("document state is complete");

                            if (document.readyState == 1)
                                console.log("document state is 1");
                        };
                    </script>
                </head>
            </html>
            """;

var browserContext = BrowsingContext.New(Configuration.Default
    .WithJs()
    .WithConsoleLogger(ctx => new ConsoleLogger())
    .WithEventLoop());

var doc = await browserContext.OpenAsync(m => m.Content(html)).WhenStable();

class ConsoleLogger : IConsoleLogger
{
    public void Log(object[] values)
    {
        var elements = values.Select(m => (m ?? String.Empty).ToString());
        var content = String.Join(", ", elements);
        Console.WriteLine(content);
    }
}

Output will be

Document OnReadyStateChange fired
1
document state is 1
Document OnReadyStateChange fired
2

Expected behavior:

document.readyState call in JavaScript should return a string of either "loading", "interactive", or "complete".

For the reproduction above, the expected output should be

Document OnReadyStateChange fired
interactive
Document OnReadyStateChange fired
complete
document state is complete

Actual behavior:

document.readyState call in JavaScript is returning the underlying enum value (ie. 0, 1, or 2)

Environment details: OS: Win11x64 Runtime: .NET 7.0.201

Possible Solution

When converting an enum value to JsValue, check if it has an official name (via DomNameAttribute), and use that value instead.

Sebbs128 commented 1 year ago

I'm currently working on this in a forked branch, just don't seem to be able to assign the issue to myself.

I have the code changes in place, just currently working through the tests (12 currently fail due to the changes)

Sebbs128 commented 1 year ago

Test failures are due to enums like AngleSharp.Dom.NodeType and AngleSharp.Js.Dom.RequesterState needing to be the enum value. Instead, opting for just addressing DocumentReadyState and leaving addressing other enums as they're brought to attention.

FlorianRappl commented 6 months ago

Landed in pre-release.