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

Idea: provide smart diffs for rendered html #101

Open
tcoopman opened this issue Oct 31, 2024 · 4 comments
Open

Idea: provide smart diffs for rendered html #101

tcoopman opened this issue Oct 31, 2024 · 4 comments
Labels
enhancement New feature or request experiment Worth pursuing but may be rejected

Comments

@tcoopman
Copy link

This is just an idea and probably out of scope for this project. On the other hand, it would be really sweet.

Right now snapshot tests for rendered HTML are kind of useless, because the rendered html is just text.

Imagine if mneme could detect the output is html parse it, and maybe provide similar tools like for regular output.

Switching with j-k could hide attributes, or hide levels of children,..

I guess this might already be simulated manually by passing the rendered html to floki.

@zachallaun
Copy link
Owner

I think this is probably a long way off, but I agree that it would be cool, so I'll leave the issue open!

Perhaps one way you could signal something like this to Mneme is to have an auto_assert/2 that looks like:

auto_assert :html, some_call_that_renders_html()

and then Mneme looks up the ":html hook" and uses it to generate and compare patterns in some non-default way. There's a lot to consider though and a lot that those kind of hooks would need to be able to do (pattern generation, matching/comparisons, diffing, converting the assertion to an ex_unit-friendly format).

@zachallaun zachallaun added enhancement New feature or request experiment Worth pursuing but may be rejected labels Nov 4, 2024
@tcoopman
Copy link
Author

tcoopman commented Nov 6, 2024

I was just playing around with Floki in combination with auto_assert.
I feel like it could already deliver value, but mneme doesn't seem to generate an option to turn something like this:

 [
                                                  {"svg",
                                                   %{
                                                     "aria-hidden" => "true",
                                                     "class" =>
                                                       "size-5 stroke-zinc-500 group-has-[[data-disabled]]:stroke-zinc-600 sm:size-4 dark:stroke-zinc-400 forced-colors:stroke-[CanvasText]",
                                                     "fill" => "none",
                                                     "viewbox" => "0 0 16 16"
                                                   },
                                                   [
                                                     {"path",
                                                      %{
                                                        "d" => "M5.75 10.75L8 13L10.25 10.75",
                                                        "strokelinecap" => "round",
                                                        "strokelinejoin" => "round",
                                                        "strokewidth" => "1.5"
                                                      }, []},
                                                     {"path",
                                                      %{
                                                        "d" => "M10.25 5.25L8 3L5.75 5.25",
                                                        "strokelinecap" => "round",
                                                        "strokelinejoin" => "round",
                                                        "strokewidth" => "1.5"
                                                      }, []}
                                                   ]}
                                                ]}

Into

                                                  {"svg", %{},
                                                   [
                                                     {"path",
                                                      %{}, []},
                                                     {"path",
                                                      %{}, []}
                                                   ]}
                                                ]}

Which would already help a bit I think

@tcoopman
Copy link
Author

tcoopman commented Nov 6, 2024

After some more toying, I've got something that's actually starting to get useful:

    x =
      render_async(view)
      |> Floki.parse_document!(attributes_as_maps: true)
      |> Floki.traverse_and_update(fn
        {tag, _attrs, children} -> {tag, [], children}
      end)
      |> Floki.find("main")
      |> Floki.raw_html()

    # |> Floki.text(sep: "-")

    auto_assert "<main><div><div><h1>\n  Publish a new workshop\n</h1><hr/><div><form><input/><section><div><h1>\n  \n          Workshop Name\n        \n</h1><p>\n  \n          This is the public name of the workshop.\n        \n</p></div><div><span><input/></span></div></section><hr/><section><div><h1>\n  \n          Workshop Description\n        \n</h1><p></p></div><div><span><textarea>\n</textarea></span></div></section><hr/><section><div><h1>\n  \n          Template\n        \n</h1><p>\n  \n          Pick a template for the new workshop.\n        \n</p></div><div><span><select><option>Workshop</option></select><span><svg><path></path><path></path></svg></span></span></div></section><hr/><div><button><span></span>Publish\n  \n</button></div></form></div></div></div></main>" <-
                  x

If I could get the output formatted a bit more nicely (without the \n - not sure why Floki is inserting them all...), that would already be great.

@zachallaun
Copy link
Owner

Regarding this:

{[
  {"svg", %{},
    [
      {"path",
      %{}, []},
      {"path",
      %{}, []}
    ]}
]}

As of #57, Mneme won't generate empty map patterns anymore, which is why this isn't being suggested.

I think the second idea is probably the way to go. In v0.10.0, if you select the """ pattern for the string, it will be retained if the output changes. Unless the strings are vastly difference, Mneme will use Myers diff to highlight the specific parts of strings that changed with underlines, which should be helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request experiment Worth pursuing but may be rejected
Projects
None yet
Development

No branches or pull requests

2 participants