Skip to content

Commit f0ceb82

Browse files
committed
playwright
1 parent d036465 commit f0ceb82

File tree

10 files changed

+346
-18
lines changed

10 files changed

+346
-18
lines changed

.examples/test-katex.stories.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from "react";
2+
3+
import { IpynbRenderer as IpynbRendererKatex } from "../src/index_katex";
4+
import testfile from "./ipynb/test.ipynb";
5+
6+
import "../src/styles/onedork.less";
7+
8+
export default {
9+
title: "Test",
10+
};
11+
12+
import "katex/dist/katex.min.css";
13+
14+
export const katex = () => {
15+
return (
16+
<>
17+
<IpynbRendererKatex
18+
ipynb={testfile} syntaxTheme="coy" />
19+
</>
20+
);
21+
};
Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from "react";
22

33
import { IpynbRenderer as IpynbRendererMathjax } from "../src/index";
4-
import { IpynbRenderer as IpynbRendererKatex } from "../src/index_katex";
54
import testfile from "./ipynb/test.ipynb";
65

76
import "../src/styles/onedork.less";
@@ -27,11 +26,3 @@ export const mathjax = () => {
2726
);
2827
};
2928

30-
export const katex = () => {
31-
return (
32-
<>
33-
<IpynbRendererKatex
34-
ipynb={testfile} syntaxTheme="coy" />
35-
</>
36-
);
37-
};

.github/workflows/e2e.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: e2e
2+
on:
3+
push:
4+
5+
jobs:
6+
run-e2e-tests:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- uses: actions/checkout@v3
11+
- name: setup python
12+
uses: actions/setup-python@v4
13+
with:
14+
python-version: "3.12"
15+
- name: setup node
16+
uses: actions/setup-node@v3
17+
with:
18+
node-version: "16"
19+
20+
- name: cache
21+
uses: actions/cache@v3
22+
with:
23+
path: |
24+
node_modules
25+
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
26+
27+
- name: install
28+
run: |
29+
yarn install
30+
npx playwright install --with-deps
31+
32+
- name: build
33+
run: yarn run storybook:build
34+
35+
- name: run server
36+
run: |
37+
python -m http.server 6006 --directory "${{ github.workspace }}/storybook-static" &
38+
39+
- name: e2e test
40+
run: yarn e2e:ci
41+
42+
- uses: actions/upload-artifact@v4
43+
with:
44+
name: playwright-results
45+
path: test-results

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,8 @@ storybook-static/
109109
.idea
110110
.DS_Store
111111

112-
*storybook.log
112+
*storybook.log
113+
/test-results/
114+
/playwright-report/
115+
/blob-report/
116+
/playwright/.cache/

e2e/katex.spec.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test('test', async ({ page }) => {
4+
await page.goto('http://localhost:6006/iframe.html?id=test--katex&viewMode=story');
5+
const cells = await page.locator('.cell').all();
6+
7+
expect(cells).toHaveLength(9);
8+
9+
{
10+
expect(await cells[0].locator('.input_prompt').textContent()).toContain('In [1]:');
11+
expect(await cells[0].locator('pre').textContent()).toContain('import matplotlib.pyplot as plt');
12+
expect(await cells[0].locator('.output_area').innerHTML()).toContain('<img src="data:image/png;base64,iVBORw0');
13+
}
14+
15+
{
16+
expect(await cells[1].locator('.input_prompt').textContent()).toContain('In [5]:');
17+
expect(await cells[1].locator('pre').textContent()).toContain('A = sy.Matrix([[2, 8], [1, 0]])');
18+
19+
const output = cells[1].locator('.output_area').first();
20+
const katex = output.locator('.katex').first();
21+
expect(await katex.innerHTML()).toContain('<span class="mord">2</span>');
22+
expect(await katex.innerHTML()).toContain('<span class="mord">8</span>');
23+
expect(await katex.innerHTML()).toContain('<span class="mord">1</span>');
24+
expect(await katex.innerHTML()).toContain('<span class="mord">0</span>');
25+
expect(await katex.innerHTML()).toContain('<span class="delimsizing size3">[</span>');
26+
expect(await katex.innerHTML()).toContain('<span class="delimsizing size3">]</span>');
27+
}
28+
29+
{
30+
expect(await cells[2].locator('.input_prompt').textContent()).toContain('In [6]:');
31+
expect(await cells[2].locator('pre').textContent()).toContain('A ** (n-1) * sy.Matrix([3, 1])');
32+
//expect(await cells[2].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="20.183ex" height="7.908ex" role="img"');
33+
}
34+
35+
{
36+
expect(await cells[3].locator('.input_prompt').textContent()).toContain('In [7]:');
37+
expect(await cells[3].locator('pre').textContent()).toContain('display(df)');
38+
const tables = await cells[3].locator('.output_area').locator('table').all();
39+
expect(tables).toHaveLength(1);
40+
const table = tables[0];
41+
expect(await table.locator('tr').count()).toBe(6);
42+
}
43+
44+
{
45+
expect(await cells[4].locator('.input_prompt').textContent()).toContain('In [9]:');
46+
expect(await cells[4].locator('.language-python').textContent()).toContain('this is a syntax error');
47+
48+
const output = cells[4].locator('.output_subarea').first();
49+
expect(output).toHaveClass(/output_error/);
50+
expect(output).toHaveCSS('background-color', 'rgba(255, 0, 0, 0.25)');
51+
//expect(output.locator('span').filter({hasText: 'File'}).first()).toHaveCSS('color', 'rgb(0, 187, 187)');
52+
//expect(output.locator('span').filter({hasText: '<ipython-input-9-4d9d942c1a8e>'}).first()).toHaveCSS('color', 'rgb(0, 187, 0)');
53+
}
54+
55+
{
56+
expect(await cells[5].locator('.input_prompt').textContent()).toContain('In [10]:');
57+
expect(await cells[5].locator('pre').textContent()).toContain('from IPython.display import Latex');
58+
expect(await cells[5].locator('.output_area').textContent()).toContain('The mass-energy equivalence is described by the famous equation');
59+
60+
const katex = cells[5].locator('.output_area').locator('.katex').first();
61+
// E = mc^2
62+
expect(await katex.innerHTML()).toContain('<span class="mord mathnormal" style="margin-right: 0.05764em;">E</span>');
63+
expect(await katex.innerHTML()).toContain('<span class="mspace" style="margin-right: 0.2778em;"></span>');
64+
expect(await katex.innerHTML()).toContain('<span class="mrel">=</span>');
65+
expect(await katex.innerHTML()).toContain('<span class="mord mathnormal">m</span>');
66+
expect(await katex.innerHTML()).toContain('<span class="mord mathnormal">c</span>');
67+
expect(await katex.innerHTML()).toContain('<span class="mord mtight">2</span>');
68+
69+
expect(await cells[5].locator('.output_area').textContent()).toContain('discovered in 1905 by Albert Einstein.');
70+
// c
71+
//expect(await cells[5].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="0.98ex" height="1.025ex" role="img"');
72+
expect(await cells[5].locator('.output_area').textContent()).toContain('the formula expresses the identity');
73+
// E = m
74+
//expect(await cells[5].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="6.732ex" height="1.724ex" role="img"');
75+
}
76+
77+
{
78+
// Markdown
79+
expect(await cells[6].locator('.input_prompt').textContent()).not.toContain('In');
80+
const output = cells[6].locator('.rendered_html').first();
81+
const header = output.locator('h1').first();
82+
expect(header).toHaveText('Markdown Cell');
83+
84+
//expect(await output.innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="23.457ex" height="2.388ex" role="img"');
85+
expect(await output.innerHTML()).toContain('<p><em>It</em> <strong>really</strong> is!!</p>');
86+
}
87+
88+
{
89+
expect(await cells[7].locator('.input_prompt').textContent()).toContain('In [11]:');
90+
expect(await cells[7].locator('.language-python').textContent()).toContain("sys.stdout.write('hello world\\n')");
91+
const outputs = await cells[7].locator('.output_area').all();
92+
expect(outputs).toHaveLength(3);
93+
expect(outputs[0].locator('.output_subarea').first()).toHaveClass(/output-stdout/);
94+
expect(outputs[1].locator('.output_subarea').first()).toHaveClass(/output-stderr/);
95+
//expect(outputs[2].locator('.output_subarea').first()).toHaveClass(/output-stdout/);
96+
}
97+
98+
{
99+
// markdown
100+
expect(await cells[8].locator('.input_prompt').textContent()).not.toContain('In');
101+
const output = cells[8].locator('.rendered_html').first();
102+
expect(await output.innerHTML()).toContain('<img src="https://github.com/righ/react-ipynb-renderer/raw/master/images/logo.png" alt="logo.png">');
103+
}
104+
105+
});

e2e/mathjax.spec.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test('test', async ({ page }) => {
4+
await page.goto('http://localhost:6006/iframe.html?id=test--mathjax&viewMode=story');
5+
const cells = await page.locator('.cell').all();
6+
7+
expect(cells).toHaveLength(9);
8+
9+
{
10+
expect(await cells[0].locator('.input_prompt').textContent()).toContain('In [1]:');
11+
expect(await cells[0].locator('pre').textContent()).toContain('import matplotlib.pyplot as plt');
12+
expect(await cells[0].locator('.output_area').innerHTML()).toContain('<img src="data:image/png;base64,iVBORw0');
13+
}
14+
15+
{
16+
expect(await cells[1].locator('.input_prompt').textContent()).toContain('In [5]:');
17+
expect(await cells[1].locator('pre').textContent()).toContain('A = sy.Matrix([[2, 8], [1, 0]])');
18+
expect(await cells[1].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="6.914ex" height="5.43ex" role="img"');
19+
}
20+
21+
{
22+
expect(await cells[2].locator('.input_prompt').textContent()).toContain('In [6]:');
23+
expect(await cells[2].locator('pre').textContent()).toContain('A ** (n-1) * sy.Matrix([3, 1])');
24+
expect(await cells[2].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="20.183ex" height="7.908ex" role="img"');
25+
}
26+
27+
{
28+
expect(await cells[3].locator('.input_prompt').textContent()).toContain('In [7]:');
29+
expect(await cells[3].locator('pre').textContent()).toContain('display(df)');
30+
const tables = await cells[3].locator('.output_area').locator('table').all();
31+
expect(tables).toHaveLength(1);
32+
const table = tables[0];
33+
expect(await table.locator('tr').count()).toBe(6);
34+
}
35+
36+
{
37+
expect(await cells[4].locator('.input_prompt').textContent()).toContain('In [9]:');
38+
expect(await cells[4].locator('.language-python').textContent()).toContain('this is a syntax error');
39+
40+
const output = cells[4].locator('.output_subarea').first();
41+
expect(output).toHaveClass(/output_error/);
42+
expect(output).toHaveCSS('background-color', 'rgba(255, 0, 0, 0.25)');
43+
//expect(output.locator('span').filter({hasText: 'File'}).first()).toHaveCSS('color', 'rgb(0, 187, 187)');
44+
//expect(output.locator('span').filter({hasText: '<ipython-input-9-4d9d942c1a8e>'}).first()).toHaveCSS('color', 'rgb(0, 187, 0)');
45+
}
46+
47+
{
48+
expect(await cells[5].locator('.input_prompt').textContent()).toContain('In [10]:');
49+
expect(await cells[5].locator('pre').textContent()).toContain('from IPython.display import Latex');
50+
expect(await cells[5].locator('.output_area').textContent()).toContain('The mass-energy equivalence is described by the famous equation');
51+
// E = mc^2
52+
expect(await cells[5].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="8.699ex" height="2.072ex" role="img"');
53+
expect(await cells[5].locator('.output_area').textContent()).toContain('discovered in 1905 by Albert Einstein.');
54+
// c
55+
expect(await cells[5].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="0.98ex" height="1.025ex" role="img"');
56+
expect(await cells[5].locator('.output_area').textContent()).toContain('the formula expresses the identity');
57+
// E = m
58+
expect(await cells[5].locator('.output_area').innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="6.732ex" height="1.724ex" role="img"');
59+
}
60+
61+
{
62+
// Markdown
63+
expect(await cells[6].locator('.input_prompt').textContent()).not.toContain('In');
64+
const output = cells[6].locator('.rendered_html').first();
65+
const header = output.locator('h1').first();
66+
expect(header).toHaveText('Markdown Cell');
67+
expect(await output.innerHTML()).toContain('<svg xmlns="http://www.w3.org/2000/svg" width="23.457ex" height="2.388ex" role="img"');
68+
expect(await output.innerHTML()).toContain('<p><em>It</em> <strong>really</strong> is!!</p>');
69+
}
70+
71+
{
72+
expect(await cells[7].locator('.input_prompt').textContent()).toContain('In [11]:');
73+
expect(await cells[7].locator('.language-python').textContent()).toContain("sys.stdout.write('hello world\\n')");
74+
const outputs = await cells[7].locator('.output_area').all();
75+
expect(outputs).toHaveLength(3);
76+
expect(outputs[0].locator('.output_subarea').first()).toHaveClass(/output-stdout/);
77+
expect(outputs[1].locator('.output_subarea').first()).toHaveClass(/output-stderr/);
78+
//expect(outputs[2].locator('.output_subarea').first()).toHaveClass(/output-stdout/);
79+
}
80+
81+
{
82+
// markdown
83+
expect(await cells[8].locator('.input_prompt').textContent()).not.toContain('In');
84+
const output = cells[8].locator('.rendered_html').first();
85+
expect(await output.innerHTML()).toContain('<img src="https://github.com/righ/react-ipynb-renderer/raw/master/images/logo.png" alt="logo.png">');
86+
}
87+
88+
});

e2e/playwright.config.ci.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineConfig } from '@playwright/test';
2+
3+
export default defineConfig({
4+
fullyParallel: true,
5+
use: {
6+
trace: 'on-first-retry',
7+
//video: 'retain-on-failure',
8+
launchOptions: {
9+
slowMo: 500,
10+
},
11+
},
12+
expect: {
13+
timeout: 10 * 1000,
14+
},
15+
});

e2e/playwright.config.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
export default defineConfig({
4+
fullyParallel: true,
5+
use: {
6+
trace: 'on-first-retry',
7+
//video: 'retain-on-failure',
8+
launchOptions: {
9+
slowMo: 500,
10+
},
11+
},
12+
expect: {
13+
timeout: 10 * 1000,
14+
},
15+
reporter: 'html',
16+
/*
17+
projects: [
18+
{
19+
name: 'chromium',
20+
use: { ...devices['Desktop Chrome'] },
21+
},
22+
23+
{
24+
name: 'firefox',
25+
use: { ...devices['Desktop Firefox'] },
26+
},
27+
28+
{
29+
name: 'webkit',
30+
use: { ...devices['Desktop Safari'] },
31+
},
32+
]
33+
*/
34+
});

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
"main": "dist/index.js",
77
"module": "dist/index.js",
88
"scripts": {
9-
"test": "echo \"Error: no test specified\" && exit 1",
109
"build": "rm -rf ./dist && webpack",
1110
"analyze": "rm -rf ./dist && webpack --analyze",
12-
"storybook": "storybook dev -p 6006",
11+
"storybook:run": "storybook dev -p 6006",
12+
"storybook:build": "storybook build",
1313
"prettier": "prettier --write \"src/**/*.{ts,tsx}\"",
1414
"eslint": "eslint --ext .ts,.tsx src",
15-
"build-storybook": "storybook build",
15+
"e2e:ui": "npx playwright test --ui",
16+
"e2e:gen": "npx playwright codegen",
17+
"e2e:run": "cd e2e && npx playwright test -c playwright.config.ts",
18+
"e2e:ci": "cd e2e && npx playwright test -c playwright.config.ci.ts",
1619
"build-default-css": "lessc --clean-css ./src/styles/default.less ./dist/styles/default.css",
1720
"build-dark-css": "lessc --clean-css ./src/styles/dark.less ./dist/styles/dark.css",
1821
"build-darkbronco-css": "lessc --clean-css ./src/styles/darkbronco.less ./dist/styles/darkbronco.css",
@@ -44,6 +47,7 @@
4447
"@babel/preset-react": "^7.13.13",
4548
"@babel/preset-typescript": "^7.13.0",
4649
"@chromatic-com/storybook": "^1.2.22",
50+
"@playwright/test": "^1.42.1",
4751
"@storybook/addon-actions": "^8.0.0",
4852
"@storybook/addon-essentials": "^8.0.0",
4953
"@storybook/addon-interactions": "^8.0.0",

0 commit comments

Comments
 (0)