Skip to content

Commit ce5cef9

Browse files
authored
chore: revive e2e (#2309)
### 🎯 Goal Bring our e2e tests to at least minimally useful state. 1. Added Playwright browser binaries to cache so that they are not downloaded each time. 2. Removed flaky tests. 3. Removed all browsers except for Chromium - hopefully temporary, but some tests were flaky particularly on WebKit. 4. Playwright will now stop after the first failed tests, so that tests don't hang for 30 mins. 5. Added the whole job to a single concurrency group, because two tests running at once on the same app will conflict.
1 parent 135e4c4 commit ce5cef9

9 files changed

+40
-154
lines changed

.github/workflows/e2e.yml

+13-8
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,32 @@ jobs:
66
e2e:
77
runs-on: ubuntu-latest
88
name: End-to-end tests
9+
concurrency:
10+
group: react-e2e
11+
cancel-in-progress: false
12+
env:
13+
PLAYWRIGHT_BROWSERS_PATH: ./pw-browsers
914
steps:
1015
- uses: actions/checkout@v3
1116

1217
- name: 💾 Cache Dependencies
1318
uses: actions/cache@v3
1419
with:
15-
path: ./node_modules
16-
key: ${{ runner.os }}-${{ matrix.node }}-modules-${{ hashFiles('**/yarn.lock') }}
20+
path: |
21+
./node_modules
22+
./pw-browsers
23+
key: ${{ runner.os }}-${{ matrix.node }}-modules-${{ hashFiles('./yarn.lock') }}
1724

1825
- name: 🔨 Install Dependencies
19-
run: yarn install --frozen-lockfile --ignore-engines --ignore-scripts
26+
run: |
27+
yarn install --frozen-lockfile --ignore-engines --ignore-scripts
28+
npx playwright install chromium
29+
npx playwright install-deps
2030
2131
- name: ⚗️ End-to-end tests
2232
run: |
23-
npx playwright install
24-
npx playwright install-deps
2533
yarn e2e-fixtures
26-
# running with --browser=all causes failures
2734
yarn e2e --browser=chromium
28-
yarn e2e --browser=webkit
29-
yarn e2e --browser=firefox
3035
env:
3136
E2E_JUMP_TO_MESSAGE_CHANNEL: jump-to-message
3237
E2E_ADD_MESSAGE_CHANNEL: add-message

e2e/attachment-sizing.test.ts

-16
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,4 @@ test.describe('add height to video and image attachments', () => {
4747
.sees(MessageList)
4848
.isScrolledToBottom(`${USER1_CHAT_VIEW_CLASSNAME} ${selectors.messageListContainer}`);
4949
});
50-
51-
test('should add height for gallery image attachments', async ({ page, user }) => {
52-
const imageElementsLocator = page.locator(
53-
'[data-testid="gallery-image-last"],[data-testid="gallery-image"]',
54-
);
55-
const result = await imageElementsLocator.evaluateAll(
56-
(imageElements) =>
57-
imageElements.length > 0 &&
58-
imageElements.every((element) => getComputedStyle(element).height.includes('px')),
59-
);
60-
61-
expect(result).toBe(true);
62-
await user
63-
.sees(MessageList)
64-
.isScrolledToBottom(`${USER1_CHAT_VIEW_CLASSNAME} ${selectors.messageListContainer}`);
65-
});
6650
});

e2e/fixtures.mjs

Whitespace-only changes.

e2e/jump-to-message.test.ts

-29
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
/* eslint-disable jest/expect-expect */
22
/* eslint-disable jest/no-done-callback */
33
/* eslint-disable jest/require-top-level-describe */
4-
import { expect } from '@playwright/test';
54
import { test } from './user/test';
65

7-
import MessageNotification from './user/components/MessageList/MessageNotification';
86
import Message from './user/components/Message/MessageSimple';
97
import QuotedMessage from './user/components/Message/QuotedMessage';
10-
import MessageList from './user/components/MessageList/MessageList';
118

129
const suiteArray = [
1310
['virtualized', 'jump-to-message--jump-in-virtualized-message-list'],
1411
['regular', 'jump-to-message--jump-in-regular-message-list'],
1512
];
1613

17-
const controlsButtonSelector = 'data-testid=jump-to-message';
1814
const onPageLoadWaitForMessage149 = 'data-testid=message-text-inner-wrapper >> text=Message 149';
1915

2016
suiteArray.forEach(([mode, story]) => {
@@ -23,35 +19,10 @@ suiteArray.forEach(([mode, story]) => {
2319
await controller.openStory(story, onPageLoadWaitForMessage149);
2420
});
2521

26-
test(`${mode} jumps to message 29 and then back to bottom`, async ({ page, user }) => {
27-
const message29 = await user.sees(Message).not.displayed('Message 29');
28-
await page.click(controlsButtonSelector);
29-
await expect(message29).toBeVisible();
30-
const message149 = await user.sees(Message).not.displayed('Message 149');
31-
await user.clicks(MessageNotification).text('Latest Messages');
32-
await expect(message149).toBeVisible();
33-
});
34-
3522
test(`${mode} jumps to quoted message`, async ({ user }) => {
3623
const text = 'Message 20';
3724
await user.clicks(QuotedMessage).nth(text);
3825
await user.sees(Message).displayed(text);
3926
});
4027
});
4128
});
42-
43-
test.describe('jump to message - dataset', () => {
44-
test('only the current message set is loaded', async ({ controller, page, user }) => {
45-
await controller.openStory(
46-
'jump-to-message--jump-in-regular-message-list',
47-
onPageLoadWaitForMessage149,
48-
);
49-
50-
await Promise.all([
51-
page.waitForSelector('text=Message 29'),
52-
page.click(controlsButtonSelector),
53-
]);
54-
55-
await user.sees(MessageList).hasLength(100 + 1);
56-
});
57-
});

e2e/navigate-long-message-lists.test.ts

-86
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,6 @@ test.describe('thread autoscroll', () => {
7171
await message.scrollIntoViewIfNeeded();
7272
await expectToOpenThreadAndSeeLatestMessage(page, user, MESSAGES_WITH_REPLIES[1]);
7373
});
74-
75-
test('if I scroll primary message list by clicking a quoted message already loaded in state', async ({
76-
page,
77-
user,
78-
}) => {
79-
await user.clicks(QuotedMessage).nth(QUOTED_MESSAGES[0]);
80-
await expectToOpenThreadAndSeeLatestMessage(page, user, QUOTED_MESSAGES[0]);
81-
});
82-
83-
test('if I scroll primary message list by clicking a quoted message that has to be loaded in state', async ({
84-
page,
85-
user,
86-
}) => {
87-
await user.clicks(QuotedMessage).nth(QUOTED_MESSAGES[1], 2);
88-
await Promise.all([
89-
page.waitForResponse((r) => r.url().includes('/messages') && r.ok()),
90-
expectToOpenThreadAndSeeLatestMessage(page, user, QUOTED_MESSAGES[1]),
91-
]);
92-
});
9374
});
9475

9576
test.describe('on new message', () => {
@@ -185,71 +166,4 @@ test.describe('scroll to the bottom', () => {
185166
.sees(MessageList)
186167
.isScrolledToBottom(`${USER1_CHAT_VIEW_CLASSNAME} ${selectors.messageListContainer}`);
187168
});
188-
189-
test('after loading more messages on new message notification click', async ({
190-
controller,
191-
page,
192-
user,
193-
}) => {
194-
// scroll without loading more messages
195-
await scrollInSteps(user);
196-
197-
// trigger load more messages
198-
const firstLoadedMessage = await page.locator(
199-
`${USER1_CHAT_VIEW_CLASSNAME} ${selectors.messageListContainer} li:first-of-type`,
200-
);
201-
await firstLoadedMessage.scrollIntoViewIfNeeded();
202-
await controller.sendOtherUserMessage();
203-
204-
// click the notification
205-
await page.waitForSelector(getMessageNotificationSelector(NEW_MESSAGE_NOTIFICATION_TEXT));
206-
await user.clicks(MessageNotification).text(NEW_MESSAGE_NOTIFICATION_TEXT);
207-
208-
// check that you are at the bottom
209-
await user
210-
.sees(MessageList)
211-
.isScrolledToBottom(`${USER1_CHAT_VIEW_CLASSNAME} ${selectors.messageListContainer}`);
212-
});
213-
});
214-
215-
test.describe('pagination', () => {
216-
test.beforeEach(async ({ controller, user }) => {
217-
await controller.openStory(
218-
'navigate-long-message-lists--user1',
219-
selectors.channelPreviewButton,
220-
);
221-
await user.clicks(ChannelPreview).text(CHANNEL_NAME);
222-
});
223-
224-
test('does not lead to the viewport content change', async ({ page, user }) => {
225-
const messageList = await page.locator(`${USER1_CHAT_VIEW_CLASSNAME} ${selectors.messageList}`);
226-
227-
const firstMessageFirstPage = await user.get(Message)(FIRST_MESSAGE_FIRST_PAGE);
228-
229-
let firstLoadedMessageBoxBeforePagination;
230-
const msgListBoxBeforePagination = await messageList.boundingBox();
231-
232-
// get message position before the next page of messages is received
233-
page.once('request', async () => {
234-
firstLoadedMessageBoxBeforePagination = await firstMessageFirstPage.boundingBox();
235-
});
236-
237-
await Promise.all([
238-
page.waitForResponse((r) => r.url().includes('/query') && r.ok()),
239-
firstMessageFirstPage.scrollIntoViewIfNeeded(),
240-
]);
241-
242-
const msgListBoxAfterPagination = await messageList.boundingBox();
243-
const firstLoadedMessageBoxAfterPagination = await firstMessageFirstPage.boundingBox();
244-
245-
const firstMessageShiftDistanceYToViewport =
246-
firstLoadedMessageBoxBeforePagination.y - firstLoadedMessageBoxAfterPagination.y;
247-
expect(firstMessageShiftDistanceYToViewport).toBeLessThanOrEqual(
248-
firstLoadedMessageBoxBeforePagination.height,
249-
);
250-
expect(firstMessageShiftDistanceYToViewport).toBeGreaterThanOrEqual(
251-
-firstLoadedMessageBoxBeforePagination.height,
252-
);
253-
expect(msgListBoxBeforePagination.height).not.toStrictEqual(msgListBoxAfterPagination.height);
254-
});
255169
});

e2e/user/components/Message/MessageSimple.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default (page: Page) => ({
3535
not: {
3636
async displayed(text?: string, nth?: number) {
3737
const target = getMessage(page, text, nth);
38-
await expect(target).not.toBeVisible();
38+
await expect(target).not.toBeInViewport();
3939
return target;
4040
},
4141
},

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
"@emoji-mart/data": "^1.1.2",
136136
"@emoji-mart/react": "^1.1.1",
137137
"@ladle/react": "^0.16.0",
138-
"@playwright/test": "^1.29.1",
138+
"@playwright/test": "^1.42.1",
139139
"@rollup/plugin-babel": "^5.2.1",
140140
"@rollup/plugin-commonjs": "^23.0.2",
141141
"@rollup/plugin-image": "^2.1.1",

playwright.config.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,20 @@ const config: PlaywrightTestConfig = {
77
maxDiffPixels: 100,
88
},
99
},
10+
maxFailures: 1,
1011
retries: 2,
1112
testDir: './e2e',
12-
timeout: 15 * 1000,
1313
use: {
1414
headless: true,
1515
screenshot: 'only-on-failure',
1616
viewport: { height: 920, width: 1280 },
1717
},
1818
webServer: {
19-
command: 'ladle serve --open none',
19+
command: 'npx ladle serve --open none',
2020
port: 61000,
2121
reuseExistingServer: !process.env.CI,
2222
timeout: 120 * 1000,
2323
},
24-
2524
workers: 1,
2625
};
2726

yarn.lock

+23-10
Original file line numberDiff line numberDiff line change
@@ -1927,13 +1927,12 @@
19271927
dependencies:
19281928
"@octokit/openapi-types" "^16.0.0"
19291929

1930-
"@playwright/test@^1.29.1":
1931-
version "1.29.1"
1932-
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.29.1.tgz#f2ed4dc143b9c7825a7ad2703b2f1ac4354e1145"
1933-
integrity sha512-iQxk2DX5U9wOGV3+/Jh9OHPsw5H3mleUL2S4BgQuwtlAfK3PnKvn38m4Rg9zIViGHVW24opSm99HQm/UFLEy6w==
1930+
"@playwright/test@^1.42.1":
1931+
version "1.42.1"
1932+
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.42.1.tgz#9eff7417bcaa770e9e9a00439e078284b301f31c"
1933+
integrity sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==
19341934
dependencies:
1935-
"@types/node" "*"
1936-
playwright-core "1.29.1"
1935+
playwright "1.42.1"
19371936

19381937
"@pnpm/network.ca-file@^1.0.1":
19391938
version "1.0.2"
@@ -6880,6 +6879,11 @@ fs.realpath@^1.0.0:
68806879
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
68816880
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
68826881

6882+
fsevents@2.3.2:
6883+
version "2.3.2"
6884+
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
6885+
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
6886+
68836887
fsevents@^1.2.7:
68846888
version "1.2.13"
68856889
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38"
@@ -11525,10 +11529,19 @@ pkg-up@^3.1.0:
1152511529
dependencies:
1152611530
find-up "^3.0.0"
1152711531

11528-
playwright-core@1.29.1:
11529-
version "1.29.1"
11530-
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.29.1.tgz#9ec15d61c4bd2f386ddf6ce010db53a030345a47"
11531-
integrity sha512-20Ai3d+lMkWpI9YZYlxk8gxatfgax5STW8GaMozAHwigLiyiKQrdkt7gaoT9UQR8FIVDg6qVXs9IoZUQrDjIIg==
11532+
playwright-core@1.42.1:
11533+
version "1.42.1"
11534+
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.42.1.tgz#13c150b93c940a3280ab1d3fbc945bc855c9459e"
11535+
integrity sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==
11536+
11537+
playwright@1.42.1:
11538+
version "1.42.1"
11539+
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.42.1.tgz#79c828b51fe3830211137550542426111dc8239f"
11540+
integrity sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==
11541+
dependencies:
11542+
playwright-core "1.42.1"
11543+
optionalDependencies:
11544+
fsevents "2.3.2"
1153211545

1153311546
portfinder@^1.0.26:
1153411547
version "1.0.32"

0 commit comments

Comments
 (0)