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

Add browser support #9

Merged
merged 5 commits into from
Oct 2, 2022
Merged

Add browser support #9

merged 5 commits into from
Oct 2, 2022

Conversation

remcohaszing
Copy link
Owner

This significantly changes how tests are run. Because we need to run tests in the browser, Playwright is used for testing. The tests now use the Playwright snapshot feature. For every input fixture a markdown and HTML snapshot are made both using the Node.js and the browser API.

To run tests in the browser, esbuild is used to serve a bundled version of the browser API. This is then dynamically imported and called inside a Playwright browser page.

Unlike the Node.js implementation, the browser implementation doesn’t support any options. Launch options are irrelevant in the browser. Mermaid configuration is global in the browser. SVG Minification is probably unneeded when used in the browser, so SVGO isn’t included.

Closes #8

This significantly changes how tests are run. Because we need to run
tests in the browser, Playwright is used for testing. The tests now use
the Playwright snapshot feature. For every input fixture a markdown and
HTML snapshot are made both using the Node.js and the browser API.

To run tests in the browser, esbuild is used to serve a bundled version
of the browser API. This is then dynamically imported and called inside
a Playwright browser page.

Unlike the Node.js implementation, the browser implementation doesn’t
support any options. Launch options are irrelevant in the browser.
Mermaid configuration is global in the browser. SVG Minification is
probably unneeded when used in the browser, so SVGO isn’t included.

Closes #8
@remcohaszing remcohaszing mentioned this pull request Sep 28, 2022
browser.ts Outdated Show resolved Hide resolved
index.ts Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@@ -43,6 +43,7 @@ jobs:
- run: npm --global install npm@8
if: ${{ matrix.node-version == 14 }}
- run: npm ci
- run: npx playwright install

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to cache the browser binaries installed?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes total sense! I’ll look into it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

microsoft/playwright#7249 may offer some ideas

@@ -0,0 +1,39 @@
import { fromDom } from 'hast-util-from-dom';
import { type Code, type Parent, type Root } from 'mdast';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this equivalent to

Suggested change
import { type Code, type Parent, type Root } from 'mdast';
import type { Code, Parent, Root } from 'mdast';

?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, those are equivalent. Because there are no ESLint rules to force a consistent way to write type imports, I have decided to disallow type imports in my personal ESLint config. However, Playwright doesn’t support unannotated type imports, so I decided to enforce type imports in this project for consistency and use a type annotation per import specifier. Using such annotations per specifier allows to combine both type imports and value imports in a single statement.

@@ -0,0 +1,2 @@
<h1>An example of a flowchart</h1>
<p><svg viewBox="0 0 124.640625 233" style="max-width: 124.640625px;" aria-labelledby="chart-title-remark-mermaid-0 chart-desc-remark-mermaid-0" role="img" xmlns="http://www.w3.org/2000/svg" width="100%" id="remark-mermaid-0"><title id="chart-title-remark-mermaid-0"></title><desc id="chart-desc-remark-mermaid-0"></desc><style>#remark-mermaid-0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#remark-mermaid-0 .error-icon{fill:#552222;}#remark-mermaid-0 .error-text{fill:#552222;stroke:#552222;}#remark-mermaid-0 .edge-thickness-normal{stroke-width:2px;}#remark-mermaid-0 .edge-thickness-thick{stroke-width:3.5px;}#remark-mermaid-0 .edge-pattern-solid{stroke-dasharray:0;}#remark-mermaid-0 .edge-pattern-dashed{stroke-dasharray:3;}#remark-mermaid-0 .edge-pattern-dotted{stroke-dasharray:2;}#remark-mermaid-0 .marker{fill:#333333;stroke:#333333;}#remark-mermaid-0 .marker.cross{stroke:#333333;}#remark-mermaid-0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#remark-mermaid-0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#remark-mermaid-0 .cluster-label text{fill:#333;}#remark-mermaid-0 .cluster-label span{color:#333;}#remark-mermaid-0 .label text,#remark-mermaid-0 span{fill:#333;color:#333;}#remark-mermaid-0 .node rect,#remark-mermaid-0 .node circle,#remark-mermaid-0 .node ellipse,#remark-mermaid-0 .node polygon,#remark-mermaid-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#remark-mermaid-0 .node .label{text-align:center;}#remark-mermaid-0 .node.clickable{cursor:pointer;}#remark-mermaid-0 .arrowheadPath{fill:#333333;}#remark-mermaid-0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#remark-mermaid-0 .flowchart-link{stroke:#333333;fill:none;}#remark-mermaid-0 .edgeLabel{background-color:#e8e8e8;text-align:center;}#remark-mermaid-0 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#remark-mermaid-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#remark-mermaid-0 .cluster text{fill:#333;}#remark-mermaid-0 .cluster span{color:#333;}#remark-mermaid-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#remark-mermaid-0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g style="opacity: 1;" id="L-A-B" class="edgePath LS-A LE-B"><path style="fill:none" marker-end="url(#arrowhead31)" d="M47.47265625,44.01492169802029L43.315755208333336,48.67910141501691C39.158854166666664,53.34328113201352,30.845052083333332,62.671640566006765,26.688151041666668,71.50248694967006C22.53125,80.33333333333333,22.53125,88.66666666666667,22.53125,92.83333333333333L22.53125,97" class="path"></path><defs><marker orient="auto" markerHeight="6" markerWidth="8" markerUnits="strokeWidth" refY="5" refX="9" viewBox="0 0 10 10" id="arrowhead31"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowheadPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker></defs></g><g style="opacity: 1;" id="L-A-C" class="edgePath LS-A LE-C"><path style="fill:none" marker-end="url(#arrowhead32)" d="M76.91015625,44.01492169802029L81.06705729166667,48.67910141501691C85.22395833333333,53.34328113201352,93.53776041666667,62.671640566006765,97.69466145833333,71.50248694967006C101.8515625,80.33333333333333,101.8515625,88.66666666666667,101.8515625,92.83333333333333L101.8515625,97" class="path"></path><defs><marker orient="auto" markerHeight="6" markerWidth="8" markerUnits="strokeWidth" refY="5" refX="9" viewBox="0 0 10 10" id="arrowhead32"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowheadPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker></defs></g><g style="opacity: 1;" id="L-B-D" class="edgePath LS-B LE-D"><path style="fill:none" marker-end="url(#arrowhead33)" d="M22.53125,136L22.53125,140.16666666666666C22.53125,144.33333333333334,22.53125,152.66666666666666,26.656901041666668,161.46244952230867C30.782552083333332,170.2582323779507,39.033854166666664,179.5164647559014,43.159505208333336,184.14558094487674L47.28515625,188.77469713385207" class="path"></path><defs><marker orient="auto" markerHeight="6" markerWidth="8" markerUnits="strokeWidth" refY="5" refX="9" viewBox="0 0 10 10" id="arrowhead33"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowheadPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker></defs></g><g style="opacity: 1;" id="L-C-D" class="edgePath LS-C LE-D"><path style="fill:none" marker-end="url(#arrowhead34)" d="M101.8515625,136L101.8515625,140.16666666666666C101.8515625,144.33333333333334,101.8515625,152.66666666666666,97.72591145833333,161.46244952230867C93.60026041666667,170.2582323779507,85.34895833333333,179.5164647559014,81.22330729166667,184.14558094487674L77.09765625,188.77469713385207" class="path"></path><defs><marker orient="auto" markerHeight="6" markerWidth="8" markerUnits="strokeWidth" refY="5" refX="9" viewBox="0 0 10 10" id="arrowhead34"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowheadPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker></defs></g></g><g class="edgeLabels"><g style="opacity: 1;" transform="" class="edgeLabel"><g class="label" transform="translate(0,0)"><rect height="0" width="0" ry="0" rx="0"></rect><foreignObject height="0" width="0"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml"><span style="" class="edgeLabel L-LS-A&#x27; L-LE-B" id="L-L-A-B"></span></div></foreignObject></g></g><g style="opacity: 1;" transform="" class="edgeLabel"><g class="label" transform="translate(0,0)"><rect height="0" width="0" ry="0" rx="0"></rect><foreignObject height="0" width="0"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml"><span style="" class="edgeLabel L-LS-A&#x27; L-LE-C" id="L-L-A-C"></span></div></foreignObject></g></g><g style="opacity: 1;" transform="" class="edgeLabel"><g class="label" transform="translate(0,0)"><rect height="0" width="0" ry="0" rx="0"></rect><foreignObject height="0" width="0"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml"><span style="" class="edgeLabel L-LS-B&#x27; L-LE-D" id="L-L-B-D"></span></div></foreignObject></g></g><g style="opacity: 1;" transform="" class="edgeLabel"><g class="label" transform="translate(0,0)"><rect height="0" width="0" ry="0" rx="0"></rect><foreignObject height="0" width="0"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml"><span style="" class="edgeLabel L-LS-C&#x27; L-LE-D" id="L-L-C-D"></span></div></foreignObject></g></g></g><g class="nodes"><g style="opacity: 1;" transform="translate(62.19140625,27.5)" id="flowchart-A-40" class="node default"><rect class="label-container" height="39" width="29.4375" y="-19.5" x="-14.71875" ry="0" rx="0"></rect><g transform="translate(0,0)" class="label"><g transform="translate(-4.71875,-9.5)"><foreignObject height="19" width="9.4375"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">A</div></foreignObject></g></g></g><g style="opacity: 1;" transform="translate(22.53125,116.5)" id="flowchart-B-41" class="node default"><rect class="label-container" height="39" width="29.0625" y="-19.5" x="-14.53125" ry="0" rx="0"></rect><g transform="translate(0,0)" class="label"><g transform="translate(-4.53125,-9.5)"><foreignObject height="19" width="9.0625"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">B</div></foreignObject></g></g></g><g style="opacity: 1;" transform="translate(101.8515625,116.5)" id="flowchart-C-43" class="node default"><rect class="label-container" height="39" width="29.578125" y="-19.5" x="-14.7890625" ry="0" rx="0"></rect><g transform="translate(0,0)" class="label"><g transform="translate(-4.7890625,-9.5)"><foreignObject height="19" width="9.578125"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">C</div></foreignObject></g></g></g><g style="opacity: 1;" transform="translate(62.19140625,205.5)" id="flowchart-D-45" class="node default"><rect class="label-container" height="39" width="29.8125" y="-19.5" x="-14.90625" ry="0" rx="0"></rect><g transform="translate(0,0)" class="label"><g transform="translate(-4.90625,-9.5)"><foreignObject height="19" width="9.8125"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">D</div></foreignObject></g></g></g></g></g></g></svg></p>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often does mermaid change its styles?
Will these snapshots break with each update?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not afraid Mermaid (or svgo) will change snapshots between updates, because this project has a lockfile.

The snapshots are inconsistent between my machine and CI though, and sometimes even between runs. This probably has the same cause as #5 and #6. I’m planning to look into this next.

@remcohaszing remcohaszing merged commit 3021ff2 into main Oct 2, 2022
@remcohaszing remcohaszing deleted the browser-support branch October 3, 2022 08:45
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

Successfully merging this pull request may close these issues.

Add browser support
4 participants