[playground] Fix broken tests

Our e2e setup with monaco is kinda brittle since it relies on the dom. It seems like longish text gets truncated so let's just simpify all these test cases.
This commit is contained in:
Lauren Tan
2024-11-18 18:34:39 -05:00
parent 0dac86f053
commit de535b1a5c
15 changed files with 148 additions and 348 deletions
@@ -1,13 +1,13 @@
function TestComponent(t0) {
  const $ = _c(2);
  const { x } = t0;
  let t1;
  if ($[0] !== x) {
    t1 = <Button>{x}</Button>;
    $[0] = x;
    $[1] = t1;
  } else {
    t1 = $[1];
  }
  return t1;
}
function TestComponent(t0) {
const $ = _c(2);
const { x } = t0;
let t1;
if ($[0] !== x) {
t1 = <Button>{x}</Button>;
$[0] = x;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
@@ -1,11 +1,11 @@
function MyApp() {
  const $ = _c(1);
  let t0;
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
    t0 = <div>Hello World</div>;
    $[0] = t0;
  } else {
    t0 = $[0];
  }
  return t0;
}
function MyApp() {
const $ = _c(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <div>Hello World</div>;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}
@@ -0,0 +1,14 @@
function TestComponent(t0) {
"use memo";
const $ = _c(2);
const { x } = t0;
let t1;
if ($[0] !== x) {
t1 = <Button>{x}</Button>;
$[0] = x;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
@@ -1,20 +0,0 @@
function anonymous_1() {
  "use no memo";
  const Avatar = () => {
    return <div>Avatar Content</div>;
  };
  const MemoizedAvatar = React.memo(Avatar);
  const Bio = () => {
    const handleBioUpdate = () => {
      console.log("Bio updated");
    };
    return <div onClick={handleBioUpdate}>Bio Content</div>;
  };
  const MemoizedBio = React.memo(Bio);
  return (
    <div>
      <MemoizedAvatar />
      <MemoizedBio />
    </div>
  );
}
@@ -1,32 +0,0 @@
function anonymous_1() {
  "use memo";
  const $ = _c(3);
  const Chart = _temp2;
  let t0;
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
    t0 = React.memo(Chart);
    $[0] = t0;
  } else {
    t0 = $[0];
  }
  const MemoizedChart = t0;
  const Graph = _temp3;
  let t1;
  if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
    t1 = React.memo(Graph);
    $[1] = t1;
  } else {
    t1 = $[1];
  }
  const MemoizedGraph = t1;
  let t2;
  if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
    t2 = (
      <div>
        <MemoizedChart />
        <MemoizedGraph />
      </div>
    );
    $[2] = t2;
  } else {
    t2 = $[2];
@@ -1,32 +0,0 @@
function App() {
  "use memo";
  const $ = _c(3);
  let t0;
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
    const Sidebar = function Sidebar() {
      const handleToggle = _temp;
      return <aside onClick={handleToggle}>Sidebar Content</
          aside>;
    };
    t0 = React.memo(Sidebar);
    $[0] = t0;
  } else {
    t0 = $[0];
  }
  const MemoizedSidebar = t0;
  let t1;
  if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
    const Content = function Content() {
      return <main>Main Content</main>;
    };
    t1 = React.memo(Content);
    $[1] = t1;
  } else {
    t1 = $[1];
  }
  const MemoizedContent = t1;
  let t2;
  if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
    t2 = (
      <div>
        <MemoizedSidebar />
@@ -1,32 +0,0 @@
function Settings() {
  "use memo";
  const $ = _c(3);
  let t0;
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
    t0 = function Preferences() {
      const handleSave = _temp;
      return <div onClick={handleSave}>Preferences Content</
          div>;
    };
    $[0] = t0;
  } else {
    t0 = $[0];
  }
  const Preferences = t0;
  let t1;
  if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
    t1 = function Notifications() {
      return <div>Notifications Settings</div>;
    };
    $[1] = t1;
  } else {
    t1 = $[1];
  }
  const Notifications = t1;
  let t2;
  if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
    t2 = (
      <div>
        <Preferences />
        <Notifications />
      </div>
@@ -1,18 +0,0 @@
function anonymous_1() {
  "use no memo";
  const Widget = function () {
    const handleExpand = () => {
      console.log("Widget expanded");
    };
    return <div onClick={handleExpand}>Widget Content</div>;
  };
  const Panel = function () {
    return <section>Panel Information</section>;
  };
  return (
    <div>
      <Widget />
      <Panel />
    </div>
  );
}
@@ -1,15 +1,13 @@
function anonymous_1() {
  const $ = _c(1);
  const handleClick = _temp;
  let t0;
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
    t0 = <h1 onClick={handleClick}>Welcome to the App!</h1>;
    $[0] = t0;
  } else {
    t0 = $[0];
  }
  return t0;
function TestComponent(t0) {
const $ = _c(2);
const { x } = t0;
let t1;
if ($[0] !== x) {
t1 = <Button>{x}</Button>;
$[0] = x;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
function _temp() {
  console.log("Header clicked");
}
@@ -1,3 +0,0 @@
function anonymous_1() {
  return <aside>Sidebar Information</aside>;
}
@@ -1,7 +1,3 @@
function anonymous_1() {
  const handleMouseOver = () => {
    console.log("Footer hovered");
  };
  return <footer onMouseOver={handleMouseOver}>Footer 
      Information</footer>;
}
function TestComponent({ x }) {
return <Button>{x}</Button>;
}
@@ -0,0 +1,28 @@
function TestComponent(t0) {
"use memo";
const $ = _c(2);
const { x } = t0;
let t1;
if ($[0] !== x) {
t1 = <Button>{x}</Button>;
$[0] = x;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
function anonymous_1(t0) {
"use memo";
const $ = _c(2);
const { x } = t0;
let t1;
if ($[0] !== x) {
t1 = <Button>{x}</Button>;
$[0] = x;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
@@ -0,0 +1,8 @@
function anonymous_1() {
"use no memo";
return <Button>{x}</Button>;
}
function anonymous_3({ x }) {
"use no memo";
return <Button>{x}</Button>;
}
@@ -7,185 +7,64 @@
import {expect, test} from '@playwright/test';
import {encodeStore, type Store} from '../../lib/stores';
import {format} from 'prettier';
test.describe.configure({mode: 'parallel'});
function concat(data: Array<string>): string {
return data.join('');
function print(data: Array<string>): Promise<string> {
return format(data.join(''), {parser: 'babel'});
}
const DIRECTIVE_TEST_CASES = [
{
name: 'module-scope-use-memo',
input: `'use memo';
const Header = () => {
const handleClick = () => {
console.log('Header clicked');
};
return <h1 onClick={handleClick}>Welcome to the App!</h1>;
};`,
input: `
'use memo';
export default function TestComponent({ x }) {
return <Button>{x}</Button>;
}`,
},
{
name: 'module-scope-use-no-memo',
input: `'use no memo';
const Footer = () => {
const handleMouseOver = () => {
console.log('Footer hovered');
};
return <footer onMouseOver={handleMouseOver}>Footer Information</footer>;
};
`,
},
{
name: 'function-scope-use-memo-function-declaration',
input: `function App() {
'use memo';
function Sidebar() {
const handleToggle = () => {
console.log('Sidebar toggled');
};
return <aside onClick={handleToggle}>Sidebar Content</aside>;
}
const MemoizedSidebar = React.memo(Sidebar);
function Content() {
return <main>Main Content</main>;
}
const MemoizedContent = React.memo(Content);
return (
<div>
<MemoizedSidebar />
<MemoizedContent />
</div>
);
input: `
'use no memo';
export default function TestComponent({ x }) {
return <Button>{x}</Button>;
}`,
},
{
name: 'function-scope-use-no-memo-function-expression',
input: `const Dashboard = function() {
'use no memo';
const Widget = function() {
const handleExpand = () => {
console.log('Widget expanded');
};
return <div onClick={handleExpand}>Widget Content</div>;
};
const Panel = function() {
return <section>Panel Information</section>;
};
return (
<div>
<Widget />
<Panel />
</div>
);
};`,
},
{
name: 'function-scope-use-memo-arrow-function-expression',
input: `const Analytics = () => {
'use memo';
const Chart = () => {
const handleRefresh = () => {
console.log('Chart refreshed');
};
return <div onClick={handleRefresh}>Chart Content</div>;
};
const MemoizedChart = React.memo(Chart);
const Graph = () => {
return <div>Graph Content</div>;
};
const MemoizedGraph = React.memo(Graph);
return (
<div>
<MemoizedChart />
<MemoizedGraph />
</div>
);
};`,
},
{
name: 'module-scope-use-no-memo-function-expression',
input: `'use no memo';
const Sidebar = function() {
return <aside>Sidebar Information</aside>;
};`,
},
{
name: 'function-scope-no-directive-arrow-function-expression',
name: 'use-memo',
input: `
const Profile = () => {
'use no memo';
const Avatar = () => {
return <div>Avatar Content</div>;
};
const MemoizedAvatar = React.memo(Avatar);
const Bio = () => {
const handleBioUpdate = () => {
console.log('Bio updated');
};
return <div onClick={handleBioUpdate}>Bio Content</div>;
};
const MemoizedBio = React.memo(Bio);
return (
<div>
<MemoizedAvatar />
<MemoizedBio />
</div>
);
function TestComponent({ x }) {
'use memo';
return <Button>{x}</Button>;
}
const TestComponent2 = ({ x }) => {
'use memo';
return <Button>{x}</Button>;
};`,
},
{
name: 'function-scope-use-no-memo-function-declaration',
input: `'use no memo';
function Settings() {
name: 'use-no-memo',
input: `
const TestComponent = function() {
'use no memo';
return <Button>{x}</Button>;
};
const TestComponent2 = ({ x }) => {
'use no memo';
return <Button>{x}</Button>;
};`,
},
{
name: 'function-scope-beats-module-scope',
input: `
'use no memo';
function TestComponent({ x }) {
'use memo';
function Preferences() {
const handleSave = () => {
console.log('Preferences saved');
};
return <div onClick={handleSave}>Preferences Content</div>;
}
function Notifications() {
return <div>Notifications Settings</div>;
}
return (
<div>
<Preferences />
<Notifications />
</div>
);
return <Button>{x}</Button>;
}`,
},
];
test('editor should open successfully', async ({page}) => {
await page.goto(`/`, {waitUntil: 'networkidle'});
await page.screenshot({
@@ -193,6 +72,7 @@ test('editor should open successfully', async ({page}) => {
path: 'test-results/00-fresh-page.png',
});
});
test('editor should compile from hash successfully', async ({page}) => {
const store: Store = {
source: `export default function TestComponent({ x }) {
@@ -208,10 +88,14 @@ test('editor should compile from hash successfully', async ({page}) => {
fullPage: true,
path: 'test-results/01-compiles-from-hash.png',
});
const userInput =
const text =
(await page.locator('.monaco-editor').nth(1).allInnerTexts()) ?? [];
expect(concat(userInput)).toMatchSnapshot('01-user-output.txt');
const output = await print(text);
expect(output).not.toEqual('');
expect(output).toMatchSnapshot('01-user-output.txt');
});
test('reset button works', async ({page}) => {
const store: Store = {
source: `export default function TestComponent({ x }) {
@@ -229,10 +113,14 @@ test('reset button works', async ({page}) => {
fullPage: true,
path: 'test-results/02-reset-button-works.png',
});
const defaultInput =
const text =
(await page.locator('.monaco-editor').nth(1).allInnerTexts()) ?? [];
expect(concat(defaultInput)).toMatchSnapshot('02-default-output.txt');
const output = await print(text);
expect(output).not.toEqual('');
expect(output).toMatchSnapshot('02-default-output.txt');
});
DIRECTIVE_TEST_CASES.forEach((t, idx) =>
test(`directives work: ${t.name}`, async ({page}) => {
const store: Store = {
@@ -245,8 +133,11 @@ DIRECTIVE_TEST_CASES.forEach((t, idx) =>
path: `test-results/03-0${idx}-${t.name}.png`,
});
const useMemoOutput =
const text =
(await page.locator('.monaco-editor').nth(1).allInnerTexts()) ?? [];
expect(concat(useMemoOutput)).toMatchSnapshot(`${t.name}-output.txt`);
const output = await print(text);
expect(output).not.toEqual('');
expect(output).toMatchSnapshot(`${t.name}-output.txt`);
}),
);
@@ -18,6 +18,8 @@ const baseURL = `http://localhost:${PORT}`;
export default defineConfig({
// Timeout per test
timeout: 30 * 1000,
// Run all tests in parallel.
fullyParallel: true,
// Test directory
testDir: path.join(__dirname, '__tests__/e2e'),
// If a test fails, retry it additional 2 times