Skip to content

Commit c44a707

Browse files
committed
review fixes wip
1 parent 2764945 commit c44a707

File tree

8 files changed

+75
-61
lines changed

8 files changed

+75
-61
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,6 @@ module.exports = {
6262
'@typescript-eslint/no-non-null-assertion': 'off',
6363
'@typescript-eslint/array-type': ['error', {default: 'array-simple'}],
6464
'@typescript-eslint/consistent-type-definitions': 'off',
65+
'curly': ['error', 'all'],
6566
},
6667
};

.github/workflows/e2e-test.yml renamed to .github/workflows/web-e2e-test.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
name: E2E Test
1+
name: Test web E2E
22
on:
33
pull_request:
44
paths:
5-
- .github/workflows/e2e-test.yml
5+
- .github/workflows/web-e2e-test.yml
66
- src/**
77
- WebExample/**
88
merge_group:
@@ -12,20 +12,20 @@ on:
1212
branches:
1313
- main
1414
paths:
15-
- .github/workflows/e2e-test.yml
15+
- .github/workflows/web-e2e-test.yml
1616
- src/**
1717
- WebExample/**
1818

1919
jobs:
20-
e2e_test:
20+
test:
2121
if: github.repository == 'Expensify/react-native-live-markdown'
2222
runs-on: ubuntu-latest
2323
defaults:
2424
run:
2525
working-directory: ./WebExample
2626

2727
concurrency:
28-
group: e2e-test-${{ github.ref }}
28+
group: web-e2e-test-${{ github.ref }}
2929
cancel-in-progress: true
3030
steps:
3131
- name: Check out Git repository
@@ -45,5 +45,5 @@ jobs:
4545
- name: Install dependencies for browsers
4646
run: npx playwright install-deps
4747

48-
- name: Run playwright tests
48+
- name: Run Playwright tests
4949
run: yarn test

WebExample/tests/.eslintrc.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module.exports = {
2-
'rules': {
2+
rules: {
33
'@lwc/lwc/no-async-await': 'off',
44
'rulesdir/prefer-import-module-contents': 'off',
5-
}
6-
}
5+
},
6+
};

WebExample/tests/input.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ test.beforeEach(async ({page}) => {
66
await page.goto(TEST_CONST.LOCAL_URL, {waitUntil: 'load'});
77
});
88

9-
test.describe('standard input behaviour', () => {
10-
test('standard input results', async ({page}) => {
9+
test.describe('typing', () => {
10+
test('short text', async ({page}) => {
1111
const inputLocator = await setupInput(page, 'clear');
1212

1313
await inputLocator.pressSequentially(TEST_CONST.EXAMPLE_CONTENT);

WebExample/tests/styles.spec.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
import {test, expect} from '@playwright/test';
22
import type {Page} from '@playwright/test';
33
import * as TEST_CONST from '../../testConstants';
4-
import {setupInput} from './utils';
4+
import {setupInput, getElementStyle} from './utils';
55

66
const testMarkdownContentStyle = async ({styleName, style, page}: {styleName: string; style: string; page: Page}) => {
77
const inputLocator = await setupInput(page);
88

99
const elementHandle = inputLocator.locator('span', {hasText: styleName}).last();
10+
const elementStyle = await getElementStyle(elementHandle);
1011

11-
let elementStyle;
12-
13-
if (elementHandle) {
14-
await elementHandle.waitFor({state: 'attached'});
15-
16-
elementStyle = await elementHandle.getAttribute('style');
17-
}
1812
expect(elementStyle).toEqual(style);
1913
};
2014

@@ -32,34 +26,34 @@ test.describe('markdown content styling', () => {
3226
await testMarkdownContentStyle({styleName: 'link', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.link.style, page});
3327
});
3428

35-
test('title', async ({page}) => {
36-
await testMarkdownContentStyle({styleName: 'title', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.title.style, page});
29+
test('h1', async ({page}) => {
30+
await testMarkdownContentStyle({styleName: 'h1', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.h1.style, page});
3731
});
3832

39-
test('code', async ({page}) => {
40-
await testMarkdownContentStyle({styleName: 'code', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.code.style, page});
33+
test('inline code', async ({page}) => {
34+
await testMarkdownContentStyle({styleName: 'inlineCode', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.inlineCode.style, page});
4135
});
4236

43-
test('codeBlock', async ({page}) => {
44-
await testMarkdownContentStyle({styleName: 'codeBlock', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.codeBlock.style, page});
37+
test('codeblock', async ({page}) => {
38+
await testMarkdownContentStyle({styleName: 'codeblock', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.codeblock.style, page});
4539
});
4640

47-
test('hereMention', async ({page}) => {
41+
test('mention-here', async ({page}) => {
4842
await testMarkdownContentStyle({styleName: 'here', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.here.style, page});
4943
});
5044

51-
test('mentionUser', async ({page}) => {
45+
test('mention-user', async ({page}) => {
5246
await testMarkdownContentStyle({styleName: 'mentionUser', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.mentionUser.style, page});
5347
});
5448

55-
test('roomMention', async ({page}) => {
49+
test('mention-report', async ({page}) => {
5650
await testMarkdownContentStyle({styleName: 'roomMention', style: TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.roomMention.style, page});
5751
});
5852

5953
test('blockquote', async ({page, browserName}) => {
6054
const blockquoteStyle = TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.blockquote.style;
6155
// Firefox border properties are serialized slightly differently
62-
const browserStyle = browserName === 'firefox' ? blockquoteStyle.replace(' border-left-style: solid', ' border-left: 6px solid gray') : blockquoteStyle;
56+
const browserStyle = browserName === 'firefox' ? blockquoteStyle.replace('border-left-style: solid', 'border-left: 6px solid gray') : blockquoteStyle;
6357

6458
await testMarkdownContentStyle({styleName: 'blockquote', style: browserStyle, page});
6559
});

WebExample/tests/textManipulation.spec.ts

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import {test, expect} from '@playwright/test';
22
import type {Locator, Page} from '@playwright/test';
33
import * as TEST_CONST from '../../testConstants';
4-
import {checkCursorPosition, setupInput} from './utils';
5-
6-
const OPERATION_MODIFIER = process.platform === 'darwin' ? 'Meta' : 'Control';
4+
import {checkCursorPosition, setupInput, getElementStyle, pressCmd} from './utils';
75

86
const pasteContent = async ({text, page, inputLocator}: {text: string; page: Page; inputLocator: Locator}) => {
97
await page.evaluate(async (pasteText) => navigator.clipboard.writeText(pasteText), text);
108
await inputLocator.focus();
11-
await inputLocator.press(`${OPERATION_MODIFIER}+v`);
9+
await pressCmd({inputLocator, command: 'v'});
1210
};
1311

1412
test.beforeEach(async ({page, context, browserName}) => {
1513
await page.goto(TEST_CONST.LOCAL_URL, {waitUntil: 'load'});
16-
if (browserName === 'chromium') await context.grantPermissions(['clipboard-write', 'clipboard-read']);
14+
if (browserName === 'chromium') {
15+
await context.grantPermissions(['clipboard-write', 'clipboard-read']);
16+
}
1717
});
1818

1919
test.describe('paste content', () => {
20-
test.skip(({browserName}) => !!process.env.CI && browserName === 'webkit', 'Excluded from webkit CI tests');
20+
test.skip(({browserName}) => !!process.env.CI && browserName === 'webkit', 'Excluded from WebKit CI tests');
2121

2222
test('paste', async ({page}) => {
2323
const PASTE_TEXT = 'bold';
@@ -29,20 +29,16 @@ test.describe('paste content', () => {
2929
await pasteContent({text: wrappedText, page, inputLocator});
3030

3131
const elementHandle = await inputLocator.locator('span', {hasText: PASTE_TEXT}).last();
32-
let elementStyle;
33-
if (elementHandle) {
34-
await elementHandle.waitFor({state: 'attached'});
32+
const elementStyle = await getElementStyle(elementHandle);
3533

36-
elementStyle = await elementHandle.getAttribute('style');
37-
}
3834
expect(elementStyle).toEqual(boldStyleDefinition.style);
3935
});
4036

4137
test('paste replace', async ({page}) => {
4238
const inputLocator = await setupInput(page, 'reset');
4339

4440
await inputLocator.focus();
45-
await inputLocator.press(`${OPERATION_MODIFIER}+a`);
41+
await pressCmd({inputLocator, command: 'a'});
4642

4743
const newText = '*bold*';
4844
await pasteContent({text: newText, page, inputLocator});
@@ -51,7 +47,7 @@ test.describe('paste content', () => {
5147
});
5248

5349
test('paste undo', async ({page, browserName}) => {
54-
test.skip(!!process.env.CI && browserName === 'firefox', 'Excluded from firefox CI tests');
50+
test.skip(!!process.env.CI && browserName === 'firefox', 'Excluded from Firefox CI tests');
5551

5652
const PASTE_TEXT_FIRST = '*bold*';
5753
const PASTE_TEXT_SECOND = '@here';
@@ -60,13 +56,13 @@ test.describe('paste content', () => {
6056

6157
await page.evaluate(async (pasteText) => navigator.clipboard.writeText(pasteText), PASTE_TEXT_FIRST);
6258

63-
await inputLocator.press(`${OPERATION_MODIFIER}+v`);
59+
await pressCmd({inputLocator, command: 'v'});
6460
await page.waitForTimeout(TEST_CONST.INPUT_HISTORY_DEBOUNCE_TIME_MS);
6561
await page.evaluate(async (pasteText) => navigator.clipboard.writeText(pasteText), PASTE_TEXT_SECOND);
66-
await inputLocator.press(`${OPERATION_MODIFIER}+v`);
62+
await pressCmd({inputLocator, command: 'v'});
6763
await page.waitForTimeout(TEST_CONST.INPUT_HISTORY_DEBOUNCE_TIME_MS);
6864

69-
await inputLocator.press(`${OPERATION_MODIFIER}+z`);
65+
await pressCmd({inputLocator, command: 'z'});
7066

7167
expect(await inputLocator.innerText()).toBe(PASTE_TEXT_FIRST);
7268
});
@@ -78,32 +74,32 @@ test.describe('paste content', () => {
7874
const inputLocator = await setupInput(page, 'clear');
7975

8076
await page.evaluate(async (pasteText) => navigator.clipboard.writeText(pasteText), PASTE_TEXT_FIRST);
81-
await inputLocator.press(`${OPERATION_MODIFIER}+v`);
77+
await pressCmd({inputLocator, command: 'v'});
8278
await page.waitForTimeout(TEST_CONST.INPUT_HISTORY_DEBOUNCE_TIME_MS);
8379
await page.evaluate(async (pasteText) => navigator.clipboard.writeText(pasteText), PASTE_TEXT_SECOND);
8480
await page.waitForTimeout(TEST_CONST.INPUT_HISTORY_DEBOUNCE_TIME_MS);
85-
await inputLocator.press(`${OPERATION_MODIFIER}+v`);
81+
await pressCmd({inputLocator, command: 'v'});
8682
await page.waitForTimeout(TEST_CONST.INPUT_HISTORY_DEBOUNCE_TIME_MS);
8783

88-
await inputLocator.press(`${OPERATION_MODIFIER}+z`);
89-
await inputLocator.press(`${OPERATION_MODIFIER}+Shift+z`);
84+
await pressCmd({inputLocator, command: 'z'});
85+
await pressCmd({inputLocator, command: 'Shift+z'});
9086

9187
expect(await inputLocator.innerText()).toBe(`${PASTE_TEXT_FIRST}${PASTE_TEXT_SECOND}`);
9288
});
9389
});
9490

95-
test('select', async ({page}) => {
91+
test('select all', async ({page}) => {
9692
const inputLocator = await setupInput(page, 'reset');
9793
await inputLocator.focus();
98-
await inputLocator.press(`${OPERATION_MODIFIER}+a`);
94+
await pressCmd({inputLocator, command: 'a'});
9995

10096
const cursorPosition = await page.evaluate(checkCursorPosition);
10197

10298
expect(cursorPosition).toBe(TEST_CONST.EXAMPLE_CONTENT.length);
10399
});
104100

105101
test('cut content changes', async ({page, browserName}) => {
106-
test.skip(!!process.env.CI && browserName === 'webkit', 'Excluded from webkit CI tests');
102+
test.skip(!!process.env.CI && browserName === 'webkit', 'Excluded from WebKit CI tests');
107103

108104
const INITIAL_CONTENT = 'bold';
109105
const WRAPPED_CONTENT = TEST_CONST.MARKDOWN_STYLE_DEFINITIONS.bold.wrapContent(INITIAL_CONTENT);
@@ -133,7 +129,7 @@ test('cut content changes', async ({page, browserName}) => {
133129
}, INITIAL_CONTENT);
134130

135131
await inputLocator.focus();
136-
await inputLocator.press(`${OPERATION_MODIFIER}+x`);
132+
await pressCmd({inputLocator, command: 'x'});
137133

138134
expect(await rootHandle.innerHTML()).toBe(EXPECTED_CONTENT);
139135
});

WebExample/tests/utils.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
1-
import type {Page} from '@playwright/test';
1+
import type {Locator, Page} from '@playwright/test';
22
import * as TEST_CONST from '../../testConstants';
33

44
const setupInput = async (page: Page, action?: 'clear' | 'reset') => {
55
const inputLocator = await page.locator(`div#${TEST_CONST.INPUT_ID}`);
6-
if (action) await page.click(`[data-testid="${action}"]`);
6+
if (action) {
7+
await page.click(`[data-testid="${action}"]`);
8+
}
79

810
return inputLocator;
911
};
1012

1113
const checkCursorPosition = () => {
1214
const editableDiv = document.querySelector('div[contenteditable="true"]') as HTMLElement;
1315
const range = window.getSelection()?.getRangeAt(0);
14-
if (!range || !editableDiv) return null;
16+
if (!range || !editableDiv) {
17+
return null;
18+
}
1519
const preCaretRange = range.cloneRange();
1620
preCaretRange.selectNodeContents(editableDiv);
1721
preCaretRange.setEnd(range.endContainer, range.endOffset);
1822
return preCaretRange.toString().length;
1923
};
2024

2125
const setCursorPosition = ({startNode, endNode}: {startNode?: Element; endNode?: Element | null}) => {
22-
if (!startNode?.firstChild || !endNode?.lastChild) return null;
26+
if (!startNode?.firstChild || !endNode?.lastChild) {
27+
return null;
28+
}
2329

2430
const range = new Range();
2531
range.setStart(startNode.firstChild, 2);
@@ -32,4 +38,21 @@ const setCursorPosition = ({startNode, endNode}: {startNode?: Element; endNode?:
3238
return selection;
3339
};
3440

35-
export {setupInput, checkCursorPosition, setCursorPosition};
41+
const getElementStyle = async (elementHandle: Locator) => {
42+
let elementStyle;
43+
44+
if (elementHandle) {
45+
await elementHandle.waitFor({state: 'attached'});
46+
47+
elementStyle = await elementHandle.getAttribute('style');
48+
}
49+
return elementStyle;
50+
};
51+
52+
const pressCmd = async ({inputLocator, command}: {inputLocator: Locator; command: string}) => {
53+
const OPERATION_MODIFIER = process.platform === 'darwin' ? 'Meta' : 'Control';
54+
55+
await inputLocator.press(`${OPERATION_MODIFIER}+${command}`);
56+
};
57+
58+
export {setupInput, checkCursorPosition, setCursorPosition, getElementStyle, pressCmd};

testConstants.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ type MarkdownStyleDefiniton = {wrapContent?: (content: string) => string; style:
55
const MARKDOWN_STYLE_DEFINITIONS = {
66
bold: {wrapContent: (content: string) => `*${content}*`, style: 'font-weight: bold;'},
77
link: {wrapContent: (content: string) => `https://${content}.com`, style: 'color: blue; text-decoration: underline;'},
8-
title: {wrapContent: (content: string) => `# ${content}`, style: 'font-size: 25px; font-weight: bold;'},
9-
code: {wrapContent: (content: string) => `\`${content}\``, style: 'font-family: monospace; font-size: 20px; color: black; background-color: lightgray;'},
10-
codeBlock: {wrapContent: (content: string) => `\`\`\`\n${content}\n\`\`\``, style: 'font-family: monospace; font-size: 20px; color: black; background-color: lightgray;'},
8+
h1: {wrapContent: (content: string) => `# ${content}`, style: 'font-size: 25px; font-weight: bold;'},
9+
inlineCode: {wrapContent: (content: string) => `\`${content}\``, style: 'font-family: monospace; font-size: 20px; color: black; background-color: lightgray;'},
10+
codeblock: {wrapContent: (content: string) => `\`\`\`\n${content}\n\`\`\``, style: 'font-family: monospace; font-size: 20px; color: black; background-color: lightgray;'},
1111
here: {wrapContent: (content: string) => `@${content}`, style: 'color: green; background-color: lime;'},
1212
mentionUser: {wrapContent: (content: string) => `@${content}@swmansion.com`, style: 'color: blue; background-color: cyan;'},
1313
blockquote: {

0 commit comments

Comments
 (0)