Skip to content

Commit 2d545e9

Browse files
committed
chore: Adds iframe helper and iframe vr test
1 parent bdef0f5 commit 2d545e9

File tree

5 files changed

+140
-3
lines changed

5 files changed

+140
-3
lines changed

pages/06-visual-tests/cartesian-tooltip.page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export default function () {
4141
<Page title="Cartesian chart tooltip visual regression page">
4242
<CoreChart
4343
{...omit(chartProps.cartesian, "ref")}
44+
ariaLabel="Line chart"
4445
options={{
45-
lang: { accessibility: { chartContainerLabel: "Line chart" } },
4646
series: series,
4747
xAxis: [{ type: "datetime", title: { text: "Time (UTC)" }, valueFormatter: dateFormatter }],
4848
yAxis: [{ title: { text: "Events" } }],
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { omit } from "lodash";
5+
6+
import CoreChart from "../../lib/components/internal-do-not-use/core-chart";
7+
import { useChartSettings } from "../common/page-settings";
8+
import { Page } from "../common/templates";
9+
import { IframeWrapper } from "../utils/iframe-wrapper";
10+
11+
export default function () {
12+
return (
13+
<IframeWrapper
14+
AppComponent={() => {
15+
const { chartProps } = useChartSettings();
16+
return (
17+
<Page title="Chart inside iframe visual regression page">
18+
<CoreChart
19+
{...omit(chartProps.pie, "ref")}
20+
ariaLabel="Pie chart"
21+
options={{
22+
series: [
23+
{
24+
name: "Resource count",
25+
type: "pie",
26+
data: [
27+
{ name: "Running", y: 60 },
28+
{ name: "Failed", y: 30 },
29+
{ name: "In-progress", y: 10 },
30+
],
31+
},
32+
],
33+
}}
34+
callback={(api) => {
35+
setTimeout(() => {
36+
if (api.chart.series) {
37+
const point = api.chart.series[0].data.find((p) => p.y === 10)!;
38+
api.highlightChartPoint(point);
39+
}
40+
}, 0);
41+
}}
42+
/>
43+
</Page>
44+
);
45+
}}
46+
/>
47+
);
48+
}

pages/06-visual-tests/pie-tooltip.page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ export default function () {
2626
return (
2727
<Page title="Pie chart tooltip visual regression page">
2828
<CoreChart
29-
{...omit(chartProps.cartesian, "ref")}
29+
{...omit(chartProps.pie, "ref")}
30+
ariaLabel="Pie chart"
3031
options={{
31-
lang: { accessibility: { chartContainerLabel: "Pie chart" } },
3232
series: series,
3333
}}
3434
chartHeight={400}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
.full-screen {
7+
inline-size: 100%;
8+
block-size: calc(
9+
100vh - var(--awsui-sticky-vertical-top-offset, 0px) - var(--awsui-sticky-vertical-bottom-offset, 0px)
10+
);
11+
border-inline: 0;
12+
border-block: 0;
13+
display: block;
14+
}

pages/utils/iframe-wrapper.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { useEffect, useRef } from "react";
5+
import { createRoot } from "react-dom/client";
6+
7+
import styles from "./iframe-wrapper.module.scss";
8+
9+
export function IframeWrapper({ id = "iframe", AppComponent }: { id?: string; AppComponent: React.ComponentType }) {
10+
const ref = useRef<HTMLDivElement>(null);
11+
12+
useEffect(() => {
13+
const container = ref.current;
14+
if (!container) {
15+
return;
16+
}
17+
const iframeEl = container.ownerDocument.createElement("iframe");
18+
iframeEl.className = styles["full-screen"];
19+
iframeEl.id = id;
20+
iframeEl.title = id;
21+
container.appendChild(iframeEl);
22+
23+
const iframeDocument = iframeEl.contentDocument!;
24+
// Prevent iframe document instance from reload
25+
// https://bugzilla.mozilla.org/show_bug.cgi?id=543435
26+
iframeDocument.open();
27+
// set html5 doctype
28+
iframeDocument.writeln("<!DOCTYPE html>");
29+
iframeDocument.close();
30+
31+
const innerAppRoot = iframeDocument.createElement("div");
32+
iframeDocument.body.appendChild(innerAppRoot);
33+
copyStyles(document, iframeDocument);
34+
iframeDocument.dir = document.dir;
35+
const syncClassesCleanup = syncClasses(document.body, iframeDocument.body);
36+
const root = createRoot(innerAppRoot);
37+
root.render(<AppComponent />);
38+
return () => {
39+
syncClassesCleanup();
40+
root.unmount();
41+
container.removeChild(iframeEl);
42+
};
43+
}, [id, AppComponent]);
44+
45+
return <div ref={ref}></div>;
46+
}
47+
48+
function copyStyles(srcDoc: Document, targetDoc: Document) {
49+
for (const stylesheet of Array.from(srcDoc.querySelectorAll("link[rel=stylesheet]"))) {
50+
const newStylesheet = targetDoc.createElement("link");
51+
for (const attr of stylesheet.getAttributeNames()) {
52+
newStylesheet.setAttribute(attr, stylesheet.getAttribute(attr)!);
53+
}
54+
targetDoc.head.appendChild(newStylesheet);
55+
}
56+
57+
for (const styleEl of Array.from(srcDoc.querySelectorAll("style"))) {
58+
const newStyle = targetDoc.createElement("style");
59+
newStyle.textContent = styleEl.textContent;
60+
targetDoc.head.appendChild(newStyle);
61+
}
62+
}
63+
64+
function syncClasses(from: HTMLElement, to: HTMLElement) {
65+
to.className = from.className;
66+
const observer = new MutationObserver(() => {
67+
to.className = from.className;
68+
});
69+
70+
observer.observe(from, { attributes: true, attributeFilter: ["class"] });
71+
72+
return () => {
73+
observer.disconnect();
74+
};
75+
}

0 commit comments

Comments
 (0)