ep_chat_log_join_leave 1.0.47 → 1.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -15,6 +15,11 @@ jobs:
|
|
|
15
15
|
uses: actions/checkout@v6
|
|
16
16
|
with:
|
|
17
17
|
repository: ether/etherpad-lite
|
|
18
|
+
path: etherpad-lite
|
|
19
|
+
- uses: actions/setup-node@v4
|
|
20
|
+
name: Install Node.js
|
|
21
|
+
with:
|
|
22
|
+
node-version: 22
|
|
18
23
|
- uses: pnpm/action-setup@v6
|
|
19
24
|
name: Install pnpm
|
|
20
25
|
with:
|
|
@@ -32,63 +37,36 @@ jobs:
|
|
|
32
37
|
restore-keys: |
|
|
33
38
|
${{ runner.os }}-pnpm-store-
|
|
34
39
|
-
|
|
35
|
-
name:
|
|
40
|
+
name: Checkout plugin repository
|
|
36
41
|
uses: actions/checkout@v6
|
|
37
42
|
with:
|
|
38
|
-
path:
|
|
39
|
-
-
|
|
40
|
-
name: export GIT_HASH to env
|
|
41
|
-
id: environment
|
|
42
|
-
run: |
|
|
43
|
-
cd ./node_modules/__tmp
|
|
44
|
-
echo "::set-output name=sha_short::$(git rev-parse --short ${{ github.sha }})"
|
|
45
|
-
-
|
|
46
|
-
name: Determine plugin name
|
|
47
|
-
id: plugin_name
|
|
48
|
-
run: |
|
|
49
|
-
cd ./node_modules/__tmp
|
|
50
|
-
npx -c 'printf %s\\n "::set-output name=plugin_name::${npm_package_name}"'
|
|
51
|
-
-
|
|
52
|
-
name: Rename plugin directory
|
|
53
|
-
env:
|
|
54
|
-
PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
|
|
55
|
-
run: |
|
|
56
|
-
mv ./node_modules/__tmp ./node_modules/"${PLUGIN_NAME}"
|
|
57
|
-
-
|
|
58
|
-
name: Install plugin dependencies
|
|
59
|
-
env:
|
|
60
|
-
PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
|
|
61
|
-
run: |
|
|
62
|
-
cd ./node_modules/"${PLUGIN_NAME}"
|
|
63
|
-
pnpm i
|
|
64
|
-
# Etherpad core dependencies must be installed after installing the
|
|
65
|
-
# plugin's dependencies, otherwise npm will try to hoist common
|
|
66
|
-
# dependencies by removing them from src/node_modules and installing them
|
|
67
|
-
# in the top-level node_modules. As of v6.14.10, npm's hoist logic appears
|
|
68
|
-
# to be buggy, because it sometimes removes dependencies from
|
|
69
|
-
# src/node_modules but fails to add them to the top-level node_modules.
|
|
70
|
-
# Even if npm correctly hoists the dependencies, the hoisting seems to
|
|
71
|
-
# confuse tools such as `npm outdated`, `npm update`, and some ESLint
|
|
72
|
-
# rules.
|
|
43
|
+
path: plugin
|
|
73
44
|
-
|
|
74
45
|
name: Install Etherpad core dependencies
|
|
46
|
+
working-directory: ./etherpad-lite
|
|
75
47
|
run: bin/installDeps.sh
|
|
48
|
+
- name: Install plugin
|
|
49
|
+
working-directory: ./etherpad-lite
|
|
50
|
+
run: |
|
|
51
|
+
pnpm run plugins i --path ../../plugin
|
|
76
52
|
- name: Create settings.json
|
|
53
|
+
working-directory: ./etherpad-lite
|
|
77
54
|
run: cp ./src/tests/settings.json settings.json
|
|
78
55
|
- name: Run the frontend tests
|
|
56
|
+
working-directory: ./etherpad-lite
|
|
79
57
|
shell: bash
|
|
80
58
|
run: |
|
|
81
59
|
pnpm run dev &
|
|
82
60
|
connected=false
|
|
83
61
|
can_connect() {
|
|
84
|
-
|
|
85
|
-
|
|
62
|
+
curl -sSfo /dev/null http://localhost:9001/ || return 1
|
|
63
|
+
connected=true
|
|
86
64
|
}
|
|
87
65
|
now() { date +%s; }
|
|
88
66
|
start=$(now)
|
|
89
|
-
while [ $(($(now) - $start)) -le
|
|
90
|
-
|
|
67
|
+
while [ $(($(now) - $start)) -le 30 ] && ! can_connect; do
|
|
68
|
+
sleep 1
|
|
91
69
|
done
|
|
92
70
|
cd src
|
|
93
|
-
pnpm exec playwright install chromium
|
|
71
|
+
pnpm exec playwright install chromium --with-deps
|
|
94
72
|
pnpm run test-ui --project=chromium
|
package/index.js
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const ChatMessage = (() => {
|
|
4
4
|
try {
|
|
5
|
-
|
|
5
|
+
// ChatMessage was migrated to TypeScript and is now exported as a
|
|
6
|
+
// named export; require() returns the whole module object, so pick
|
|
7
|
+
// the class out of it. Fall back to the legacy default export shape
|
|
8
|
+
// for older Etherpad releases.
|
|
9
|
+
const mod = require('ep_etherpad-lite/static/js/ChatMessage');
|
|
10
|
+
return mod.ChatMessage || mod.default || mod;
|
|
6
11
|
} catch (err) {
|
|
7
12
|
return null;
|
|
8
13
|
}
|
package/package.json
CHANGED
package/static/css/index.css
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The join/leave entries are rendered as <div> rather than <p> so test
|
|
3
|
+
* locators that target real chat (`#chattext p`) don't trip on them.
|
|
4
|
+
* Core (pad/chat.css) and the colibris skin both style `#chattext p`
|
|
5
|
+
* directly though — mirror those rules here so the entries still look
|
|
6
|
+
* flush with regular chat lines. Padding matches the colibris override
|
|
7
|
+
* (4px 10px) since that's the default shipped skin.
|
|
8
|
+
*/
|
|
1
9
|
#chattext .ep_chat_log_join_leave-join,
|
|
2
10
|
#chattext .ep_chat_log_join_leave-leave {
|
|
11
|
+
padding: 4px 10px;
|
|
12
|
+
overflow-x: hidden;
|
|
13
|
+
white-space: pre-wrap;
|
|
14
|
+
word-wrap: break-word;
|
|
3
15
|
font-size: smaller;
|
|
4
16
|
font-style: italic;
|
|
5
17
|
}
|
package/static/js/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// pad_utils was migrated to TypeScript; the PadUtils singleton is now
|
|
4
|
+
// the default export rather than a named `padutils` property. Pull the
|
|
5
|
+
// default with a fallback to the legacy named export for older
|
|
6
|
+
// Etherpad releases.
|
|
7
|
+
const padUtilsMod = require('ep_etherpad-lite/static/js/pad_utils');
|
|
8
|
+
const padutils = padUtilsMod.default || padUtilsMod.padutils;
|
|
4
9
|
|
|
5
10
|
// In case a translation is missing.
|
|
6
11
|
const defaultMsg = {
|
|
@@ -19,13 +24,15 @@ exports.chatNewMessage = async (hookName, context) => {
|
|
|
19
24
|
if (!['join', 'leave'].includes(type)) throw new Error(`Unexpected message type: ${type}`);
|
|
20
25
|
const typeId = `ep_chat_log_join_leave-${type}`; // Used for classes and html10n.
|
|
21
26
|
|
|
22
|
-
// Because the default rendering is overridden below, context.text and context.authorName are
|
|
23
|
-
// ignored except for the gritter pop-up.
|
|
24
27
|
if (!context.authorName) context.authorName = context.author;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
// Suppress core's "new chat message" gritter (chat.ts triggers it whenever
|
|
29
|
+
// chat is closed and ctx.duration > 0). Join/leave events are not chat
|
|
30
|
+
// messages users sent, and surfacing them as gritters has surprising
|
|
31
|
+
// side-effects: the popup is often the first .gritter-item in the DOM, so
|
|
32
|
+
// unrelated tests that wait for a gritter (e.g. core's
|
|
33
|
+
// error_sanitization.spec) grab "unnamedjoined the pad" instead of the
|
|
34
|
+
// gritter they actually triggered.
|
|
35
|
+
context.duration = 0;
|
|
29
36
|
|
|
30
37
|
// Override the default rendering.
|
|
31
38
|
const timeElt = document.createElement('span');
|
|
@@ -38,7 +45,11 @@ exports.chatNewMessage = async (hookName, context) => {
|
|
|
38
45
|
msgElt.classList.add('ep_chat_log_join_leave-message');
|
|
39
46
|
msgElt.dataset.l10nId = typeId;
|
|
40
47
|
msgElt.append(defaultMsg[type]);
|
|
41
|
-
|
|
48
|
+
// Etherpad core appends real chat messages to #chattext as <p>. Tests
|
|
49
|
+
// (and other plugins) often locate them with `#chattext p` in strict
|
|
50
|
+
// mode, which then trips on these synthetic join/leave entries.
|
|
51
|
+
// Render them as <div> so plain `p` selectors only match real chat.
|
|
52
|
+
context.rendered = document.createElement('div');
|
|
42
53
|
context.rendered.classList.add(typeId);
|
|
43
54
|
context.rendered.append(timeElt, nameElt, ' ', msgElt);
|
|
44
55
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {expect, test} from '@playwright/test';
|
|
2
|
+
import {getPadBody, goToNewPad} from 'ep_etherpad-lite/tests/frontend-new/helper/padHelper';
|
|
3
|
+
|
|
4
|
+
test.beforeEach(async ({page}) => {
|
|
5
|
+
await goToNewPad(page);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test.describe('ep_chat_log_join_leave', () => {
|
|
9
|
+
test('pad loads with plugin installed', async ({page}) => {
|
|
10
|
+
const padBody = await getPadBody(page);
|
|
11
|
+
await expect(padBody).toBeVisible();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// The join message should not be a <p>, so core / other-plugin tests
|
|
15
|
+
// that strict-mode-locate `#chattext p` (the user's actual chat) don't
|
|
16
|
+
// collide with the synthetic join entry. See change_user_color.spec.ts
|
|
17
|
+
// upstream for the failure mode. Chat is collapsed by default, so the
|
|
18
|
+
// entry isn't "visible" — assert presence instead.
|
|
19
|
+
test('join entry is rendered as a <div>, not a <p>', async ({page}) => {
|
|
20
|
+
await expect(page.locator('#chattext > div.ep_chat_log_join_leave-join'))
|
|
21
|
+
.toHaveCount(1, {timeout: 30_000});
|
|
22
|
+
await expect(page.locator('#chattext > p.ep_chat_log_join_leave-join')).toHaveCount(0);
|
|
23
|
+
});
|
|
24
|
+
});
|