@camunda/e2e-test-suite 0.0.1235 → 0.0.1236

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.
@@ -6,6 +6,8 @@ declare class OperateHomePage {
6
6
  readonly informationDialog: Locator;
7
7
  readonly editVariableButton: Locator;
8
8
  readonly variableValueInput: Locator;
9
+ readonly variableValueEditor: Locator;
10
+ readonly variableValueContent: Locator;
9
11
  readonly saveVariableButton: Locator;
10
12
  readonly editVariableSpinner: Locator;
11
13
  constructor(page: Page);
@@ -9,6 +9,8 @@ class OperateHomePage {
9
9
  informationDialog;
10
10
  editVariableButton;
11
11
  variableValueInput;
12
+ variableValueEditor;
13
+ variableValueContent;
12
14
  saveVariableButton;
13
15
  editVariableSpinner;
14
16
  constructor(page) {
@@ -28,6 +30,21 @@ class OperateHomePage {
28
30
  });
29
31
  this.editVariableButton = page.getByTestId('edit-variable-button');
30
32
  this.variableValueInput = page.getByTestId('edit-variable-value');
33
+ // "The row is in write mode." InlineJsonEditor renders a CodeMirror
34
+ // instance carrying this test id only on its editable branch; the
35
+ // read-only branch renders ReadOnlyEditor instead, with no CodeMirror
36
+ // at all. The product's own suite resolves the editor the same way --
37
+ // see camunda/camunda
38
+ // qa/c8-orchestration-cluster-e2e-test-suite/pages/OperateHomePage.ts.
39
+ this.variableValueEditor = page.getByTestId('code-mirror-editor');
40
+ // The editable node *inside* that container. CodeMirror puts its
41
+ // contenteditable on `.cm-content`, so that -- not the container -- is
42
+ // what takes focus and what holds the text. Asserting focus on the
43
+ // container reports `inactive` even when the caret is correctly placed,
44
+ // because clicking the container focuses its contenteditable child.
45
+ this.variableValueContent = this.variableValueEditor
46
+ .locator('.cm-content')
47
+ .first();
31
48
  // Carbon icon-only buttons expose their accessible name via aria-labelledby
32
49
  // (tooltip text "Save") which overrides aria-label for computed accessible name.
33
50
  // Use a CSS attribute selector to match the raw aria-label attribute directly.
@@ -56,8 +73,34 @@ class OperateHomePage {
56
73
  throw new Error(`Failed to click the processes tab after ${maxRetries} attempts.`);
57
74
  }
58
75
  async clickEditVariableButton(variableName) {
59
- const editVariableButton = 'variable-' + variableName;
60
- await this.page.getByTestId(editVariableButton).getByLabel('Edit').click();
76
+ const editVariableButton = this.page
77
+ .getByTestId('variable-' + variableName)
78
+ .getByLabel('Edit');
79
+ await (0, test_1.expect)(editVariableButton).toBeVisible({ timeout: 30000 });
80
+ // The caller reaches this straight out of activeIconAssertion, which
81
+ // reloads the page while it polls for the status icon, so the variables
82
+ // panel is usually still mounting when the click lands. A click during
83
+ // that render resolves without raising and without effect: the row stays
84
+ // read-only, InlineJsonEditor keeps rendering ReadOnlyEditor, and the
85
+ // editor the next step needs is never created. Retry until write mode is
86
+ // actually active rather than asserting on the editor afterwards and
87
+ // reporting the dropped click as a missing element.
88
+ //
89
+ // Only click while the row is still read-only. Entering write mode
90
+ // replaces the Edit control, so once the click has taken, clicking again
91
+ // just waits out its timeout against an element that is gone or still
92
+ // being replaced -- which is what the retry did on the slower macOS and
93
+ // Windows runners, where the editor needs longer to mount than one
94
+ // iteration allowed: it re-clicked, exhausted the budget, and raised the
95
+ // click timeout instead of the state the row was actually in. Probing
96
+ // first keeps the retry for a genuinely dropped click and turns the slow
97
+ // case into what it should be, a wait.
98
+ await (0, test_1.expect)(async () => {
99
+ if (await editVariableButton.isVisible()) {
100
+ await editVariableButton.click({ timeout: 10000 });
101
+ }
102
+ await (0, test_1.expect)(this.variableValueEditor).toBeVisible({ timeout: 15000 });
103
+ }).toPass({ timeout: 90000 });
61
104
  }
62
105
  async clickVariableValueInput() {
63
106
  await this.variableValueInput.click();
@@ -69,15 +112,18 @@ class OperateHomePage {
69
112
  // Operate migrated this editor from Monaco to CodeMirror
70
113
  // (@uiw/react-codemirror; see camunda/camunda#62782) -- the editable
71
114
  // region is now a div.cm-content, not .monaco-editor, and it no longer
72
- // exposes a Monaco-style .cursor element. clickEditVariableButton still
73
- // triggers autoFocus, so wait for the content element to actually have
74
- // focus (:focus) before sending events, same intent as the old cursor
75
- // check. Scoped to the variable row to avoid matching other editors.
76
- const variableRow = this.page.getByTestId('variable-testVariable');
77
- await variableRow
78
- .locator('.cm-content:focus')
79
- .first()
80
- .waitFor({ state: 'visible', timeout: 30000 });
115
+ // exposes a Monaco-style .cursor element.
116
+ //
117
+ // clickEditVariableButton has already established that the editor exists
118
+ // -- it retries the Edit click until it does -- so this only has to put
119
+ // the caret in it. Do not wait on focus arriving by itself: autoFocus
120
+ // fires when the editor mounts, which is before this runs, so a wait for
121
+ // `:focus` can only ever observe focus that has already been placed
122
+ // elsewhere. Click to focus, then confirm. Both act on the
123
+ // contenteditable rather than its container, which cannot hold focus.
124
+ await (0, test_1.expect)(this.variableValueContent).toBeVisible({ timeout: 30000 });
125
+ await this.variableValueContent.click();
126
+ await (0, test_1.expect)(this.variableValueContent).toBeFocused({ timeout: 10000 });
81
127
  // Insert the COMPLETE JSON value, both quotes included. Monaco used to
82
128
  // auto-close a lone opening quote, so the old recipe inserted only
83
129
  // `"value`; CodeMirror's closeBrackets extension ignores insertions
@@ -97,7 +143,9 @@ class OperateHomePage {
97
143
  await this.page.keyboard.press('Backspace');
98
144
  const jsonValue = JSON.stringify(newValue);
99
145
  await this.page.keyboard.insertText(jsonValue);
100
- await (0, test_1.expect)(variableRow.locator('.cm-content').first()).toContainText(jsonValue, { timeout: 10000 });
146
+ await (0, test_1.expect)(this.variableValueContent).toContainText(jsonValue, {
147
+ timeout: 10000,
148
+ });
101
149
  }
102
150
  async clickSaveVariableButton() {
103
151
  await this.saveVariableButton.click({ timeout: 30000 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1235",
3
+ "version": "0.0.1236",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",