graphdb-workbench-tests 3.1.0-WBM-9 → 3.1.0-plugins1

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.
Files changed (71) hide show
  1. package/.nycrc +10 -0
  2. package/cypress-legacy.config.js +9 -1
  3. package/cypress-security.config.js +40 -0
  4. package/cypress.config.js +3 -1
  5. package/e2e-flaky/import/import-user-data-url.spec.js +63 -0
  6. package/e2e-legacy/explore/graphs-overview/graphs.overview.spec.js +1 -1
  7. package/e2e-legacy/graphql/filter-graphql-endpoints-on-management-view.spec.js +1 -4
  8. package/e2e-legacy/graphql/graphql-endpoint-management-view.spec.js +4 -4
  9. package/e2e-legacy/graphql/import-graphql-endpoint-definitions.spec.js +1 -10
  10. package/e2e-legacy/home/cookie-policy.spec.js +78 -59
  11. package/e2e-legacy/home/documentation-link.spec.js +31 -33
  12. package/e2e-legacy/home/google-analytics.spec.js +4 -6
  13. package/e2e-legacy/home/rdf-resource-search.spec.js +106 -138
  14. package/e2e-legacy/home/view-resource-autocomplete.spec.js +28 -15
  15. package/e2e-legacy/import/import-user-data-url.spec.js +0 -23
  16. package/e2e-legacy/import/import-user-data.spec.js +1 -2
  17. package/e2e-legacy/monitor/global-operation-statuses-component.spec.js +13 -9
  18. package/e2e-legacy/repository/repositories.spec.js +6 -6
  19. package/e2e-legacy/setup/autocomplete/autocomplete.spec.js +3 -4
  20. package/e2e-legacy/setup/jdbc/jdbc-create.spec.js +2 -2
  21. package/e2e-legacy/setup/sparql-template/sparql-template-create.js +10 -3
  22. package/e2e-legacy/setup/users-and-access/user-and-access.spec.js +38 -9
  23. package/e2e-legacy/sparql-editor/saved-query/edit-query.spec.js +3 -6
  24. package/e2e-legacy/sparql-editor/saved-query/share-query.spec.js +2 -2
  25. package/e2e-legacy/ttyg/agent-list.spec.js +37 -2
  26. package/e2e-legacy/ttyg/chat-list.spec.js +1 -2
  27. package/e2e-legacy/ttyg/clone-agent.spec.js +1 -0
  28. package/e2e-legacy/ttyg/create-agent.spec.js +7 -6
  29. package/e2e-legacy/ttyg/edit-agent.spec.js +69 -9
  30. package/e2e-legacy/ttyg/ttyg-initial-state-with-selected-repository.spec.js +4 -2
  31. package/e2e-legacy/ttyg/ttyg-permission.spec.js +28 -20
  32. package/e2e-security/setup/home/cookie-policy.spec.js +64 -0
  33. package/e2e-security/setup/users-and-access/create-user-permissions.spec.js +184 -0
  34. package/e2e-security/setup/users-and-access/graphql-user.spec.js +123 -0
  35. package/e2e-security/setup/users-and-access/repo-admin-role.spec.js +69 -0
  36. package/e2e-security/setup/users-and-access/turn-on-security-and-password-change.spec.js +87 -0
  37. package/e2e-security/setup/users-and-access/user-and-access.spec.js +87 -0
  38. package/e2e-security/setup/users-and-access/users-and-access-initial-state.spec.js +38 -0
  39. package/fixtures/repositories/free-access.json +13 -0
  40. package/fixtures/ttyg/agent/get-agent-defaults-assistant-api.json +44 -0
  41. package/fixtures/ttyg/agent/get-agent-defaults.json +2 -0
  42. package/npm-shrinkwrap.json +7574 -1775
  43. package/package.json +9 -3
  44. package/plugins/index.js +1 -0
  45. package/steps/base-steps.js +4 -0
  46. package/steps/error-steps.js +4 -7
  47. package/steps/graphql/graphql-endpoint-management-steps.js +1 -1
  48. package/steps/home-steps.js +57 -32
  49. package/steps/import/import-steps.js +2 -2
  50. package/steps/login-steps.js +11 -0
  51. package/steps/main-menu-steps.js +13 -6
  52. package/steps/operations-statuses-component-steps.js +5 -10
  53. package/steps/rdf-resource-search-steps.js +55 -0
  54. package/steps/repository-steps.js +1 -0
  55. package/steps/setup/autocomplete-steps.js +4 -0
  56. package/steps/setup/settings-steps.js +18 -0
  57. package/steps/setup/user-and-access-steps.js +24 -2
  58. package/steps/ttyg/ttyg-agent-settings-modal.steps.js +74 -11
  59. package/steps/ttyg/ttyg-view-steps.js +19 -4
  60. package/steps/widgets/active-repository-widget-steps.js +4 -0
  61. package/steps/yasgui/yasr-steps.js +4 -0
  62. package/stubs/browser-stubs.js +21 -0
  63. package/stubs/environment-stubs.js +9 -1
  64. package/stubs/repositories/repositories-stubs.js +4 -0
  65. package/stubs/security-stubs.js +4 -0
  66. package/stubs/ttyg/ttyg-stubs.js +18 -2
  67. package/support/e2e.js +2 -1
  68. package/support/repository-commands.js +14 -1
  69. package/e2e-flaky/setup/users-and-access/security-and-free-access.spec.js +0 -57
  70. package/e2e-flaky/ttyg/ttyg-permission.spec.js +0 -67
  71. package/fixtures/locale-en.json +0 -3361
package/package.json CHANGED
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "3.1.0-WBM-9",
3
+ "version": "3.1.0-plugins1",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "scripts": {
6
6
  "prepack": "npm shrinkwrap",
7
7
  "postpack": "mv npm-shrinkwrap.json package-lock.json",
8
8
  "cy:open": "cypress open",
9
9
  "cy:open-legacy": "cypress open --config-file cypress-legacy.config.js",
10
+ "cy:open-security": "cypress open --config-file cypress-security.config.js",
10
11
  "cy:open-flaky": "cypress open --config-file cypress-flaky.config.js",
11
12
  "cy:run": "npm run cy:run-legacy && cypress run",
12
- "cy:run:partial": "cypress run --config-file cypress-legacy.config.js --spec \"e2e-legacy/graphql/graphql-endpoint-management-view.spec.js\" --browser chrome",
13
+ "cy:run:partial": "cypress run --config-file cypress-legacy.config.js --spec \"e2e-legacy/**/jdbc-create.spec.js\" --browser chrome",
13
14
  "cy:run-legacy": "cypress run --config-file cypress-legacy.config.js --browser chrome",
15
+ "cy:run-security": "cypress run --config-file cypress-security.config.js --browser chrome",
16
+ "cy:run-legacy:coverage": "cypress run --config-file cypress-legacy.config.js --browser chrome",
14
17
  "cy:run-flaky": "cypress run --config-file cypress-flaky.config.js --browser chrome",
15
18
  "test": "npm run cy:run-legacy",
16
19
  "test:core": "cypress run --spec e2e-legacy/repository/**,e2e-legacy/import/**,e2e-legacy/sparql-editor/**,e2e-legacy/monitor/**,e2e-legacy/cluster/**,e2e-legacy/ttyg/**"
@@ -29,7 +32,9 @@
29
32
  "url": "git+https://github.com/Ontotext-AD/graphdb-workbench.git"
30
33
  },
31
34
  "devDependencies": {
32
- "cypress": "^14.5.0",
35
+ "@bahmutov/cypress-code-coverage": "^2.7.2",
36
+ "babel-plugin-istanbul": "^7.0.0",
37
+ "cypress": "14.5.1",
33
38
  "cypress-failed-log": "^2.10.0",
34
39
  "cypress-file-upload": "^5.0.8",
35
40
  "cypress-localstorage-commands": "^2.2.7",
@@ -38,6 +43,7 @@
38
43
  "cypress-terminal-report": "^7.2.0",
39
44
  "cypress-wait-until": "^3.0.2",
40
45
  "del": "^8.0.0",
46
+ "dotenv": "^17.0.1",
41
47
  "minimist": "^1.2.8",
42
48
  "mocha-junit-reporter": "^2.2.1"
43
49
  }
package/plugins/index.js CHANGED
@@ -95,4 +95,5 @@ module.exports = (on, config) => {
95
95
  printGroup('[FAIL] Broken tests', broken);
96
96
  console.log('====================================================================================================\n');
97
97
  });
98
+ return config;
98
99
  };
@@ -14,4 +14,8 @@ export class BaseSteps {
14
14
  static getByTestId(testId) {
15
15
  return cy.getByTestId(testId);
16
16
  }
17
+
18
+ static typeEscapeKey() {
19
+ cy.get('body').type('{esc}');
20
+ }
17
21
  }
@@ -1,16 +1,13 @@
1
1
  export class ErrorSteps {
2
- static getErrorElement() {
3
- return cy.get('.idError');
4
- }
5
-
6
- static verifyError(errorMessage) {
7
- ErrorSteps.getErrorElement().contains(errorMessage);
8
- }
9
2
 
10
3
  static getRepositoryErrors() {
11
4
  return cy.get('.card.repository-errors')
12
5
  }
13
6
 
7
+ static verifyError(errorMessage) {
8
+ ErrorSteps.getRepositoryErrors().contains(errorMessage);
9
+ }
10
+
14
11
  static getNoConnectedRepoMessage() {
15
12
  return this.getRepositoryErrors().find('.alert.lead.alert-info');
16
13
  }
@@ -89,7 +89,7 @@ export class GraphqlEndpointManagementSteps {
89
89
  const endpointInfo = data[index];
90
90
  cy.wrap($row).within(() => {
91
91
  const statusCheck = endpointInfo.status === 'deleted' ? 'not.exist' : 'be.visible';
92
- cy.get('td').eq(1).find('.endpoint-link').should(statusCheck);
92
+ cy.get('td').eq(2).find('.endpoint-link').should(statusCheck);
93
93
  cy.get('td').eq(2).should('contain', endpointInfo.id);
94
94
  cy.get('td').eq(3).should('contain', endpointInfo.label);
95
95
  const isDefaultCheck = endpointInfo.default ? 'be.checked' : 'not.be.checked'
@@ -3,26 +3,34 @@ import {RepositoryErrorsWidgetSteps} from "./widgets/repository-errors-widget-st
3
3
  import {ActiveRepositoryWidgetSteps} from "./widgets/active-repository-widget-steps";
4
4
  import {SavedSparqlQueriesWidgetSteps} from "./widgets/saved-sparql-queries-widget-steps";
5
5
  import {RepositorySteps} from "./repository-steps";
6
+ import {BaseSteps} from "./base-steps";
7
+ import {EnvironmentStubs} from "../stubs/environment-stubs";
6
8
 
7
- class HomeSteps {
9
+ class HomeSteps extends BaseSteps {
8
10
 
9
11
  static visit() {
10
12
  cy.visit('/');
11
13
  HomeSteps.getTutorialPanel().should('be.visible');
12
14
  }
13
15
 
14
- static visitAndWaitLoader(stubNewWindow) {
15
- if (stubNewWindow) {
16
- cy.visit('/', {
17
- onBeforeLoad (win) {
18
- cy.stub(win, 'open').as('window.open');
19
- }
20
- });
21
- } else {
22
- cy.visit('/');
23
- }
16
+ static visitInProdMode() {
17
+ cy.visit('/', {
18
+ onBeforeLoad: (win) => {
19
+ EnvironmentStubs.stubWbProdMode();
20
+ }
21
+ });
22
+ }
23
+
24
+ static visitInDevMode() {
25
+ cy.visit('/', {
26
+ onBeforeLoad: (win) => {
27
+ EnvironmentStubs.stubWbDevMode();
28
+ }
29
+ });
30
+ }
24
31
 
25
- cy.window();
32
+ static visitAndWaitLoader() {
33
+ cy.visit('/');
26
34
  return cy.get('.ot-loader-new-content').should('not.exist');
27
35
  }
28
36
 
@@ -170,10 +178,14 @@ class HomeSteps {
170
178
  });
171
179
  }
172
180
 
181
+ static getCreateRepositoryLink() {
182
+ return cy.get('.create-repository-btn');
183
+ }
184
+
173
185
  static verifyCreateRepositoryLink() {
174
186
  cy.get('.card.repository-errors').should("be.visible")
175
187
  .within(() => {
176
- cy.get('.create-repository-btn')
188
+ HomeSteps.getCreateRepositoryLink()
177
189
  .click()
178
190
  .url()
179
191
  .should('eq', Cypress.config("baseUrl") + '/repository/create?previous=home');
@@ -233,19 +245,40 @@ class HomeSteps {
233
245
  cy.wait('@getAutocompleteStatus').then(callback);
234
246
  }
235
247
 
236
- static openRdfSearchBox() {
237
- cy.get('.search-rdf-btn').click();
238
- cy.get('.search-rdf-input').should('be.visible');
239
- cy.get('.search-rdf-input search-resource-input .view-res-input').should('be.visible')
240
- .and('be.focused');
248
+ static getRdfResourceSearchComponent() {
249
+ return this.getByTestId('search-rdf-resource-component');
250
+ }
251
+
252
+ static getRdfResourceSearchInput() {
253
+ return this.getRdfResourceSearchComponent().getByTestId('rdf-resource-input');
254
+ }
255
+
256
+ static getAutocompleteResultsContainer() {
257
+ return this.getRdfResourceSearchComponent().getByTestId('auto-complete-results');
258
+ }
259
+
260
+ static getAutocompleteSuggestion() {
261
+ return this.getAutocompleteResultsContainer().getByTestId('autocomplete-suggestion');
241
262
  }
242
263
 
243
- static doNotOpenRdfSearchBoxButFocusResourceSearch() {
244
- cy.get('.search-rdf-btn').click();
245
- cy.get('.search-rdf-input').should('not.exist');
246
- cy.get('.search-rdf-input search-resource-input .view-res-input').should('not.exist');
247
- cy.get('#search-resource-input-home > #search-resource-box > input').should('be.visible')
248
- .and('be.focused');
264
+ static getAutocompleteSuggestionByPartialText(partialText) {
265
+ return this.getAutocompleteSuggestion().contains(partialText);
266
+ }
267
+
268
+ static getTableDisplayButton() {
269
+ return this.getRdfResourceSearchComponent().getByTestId('display-table-button');
270
+ }
271
+
272
+ static getVisualDisplayButton() {
273
+ return this.getRdfResourceSearchComponent().getByTestId('display-visual-button');
274
+ }
275
+
276
+ static getRdfResourceSearchCloseButton() {
277
+ return this.getRdfResourceSearchComponent().getByTestId('rdf-resource-clear-button');
278
+ }
279
+
280
+ static closeRdfResourceSearchBox() {
281
+ this.getRdfResourceSearchCloseButton().click();
249
282
  }
250
283
 
251
284
  static getViewResourceAsLabel() {
@@ -288,14 +321,6 @@ class HomeSteps {
288
321
  return cy.get('.cookie-policy-modal');
289
322
  }
290
323
 
291
- static getHelpMenu() {
292
- return cy.get('.main-menu .menu-element-root').eq(8);
293
- }
294
-
295
- static clickHelpMenu() {
296
- return HomeSteps.getHelpMenu().click();
297
- }
298
-
299
324
  static getDocumentationLink() {
300
325
  return cy.get('[guide-selector="sub-menu-documentation"]');
301
326
  }
@@ -35,7 +35,7 @@ class ImportSteps {
35
35
  }
36
36
 
37
37
  static showPageInfoPopover() {
38
- return this.getPageInfoIcon().realHover();
38
+ return this.getPageInfoIcon().trigger('mouseover');
39
39
  }
40
40
 
41
41
  static getPageInfoPopover() {
@@ -47,7 +47,7 @@ class ImportSteps {
47
47
  }
48
48
 
49
49
  static hidePageInfoPopover() {
50
- return cy.get('.menu-element-root').realHover();
50
+ return this.getPageInfoIcon().trigger('mouseleave');
51
51
  }
52
52
 
53
53
  static visitUserImport(repository) {
@@ -1,9 +1,20 @@
1
+ import {EnvironmentStubs} from "../stubs/environment-stubs";
2
+
1
3
  export class LoginSteps {
2
4
  static visitLoginPage() {
3
5
  cy.visit('/login');
4
6
  }
5
7
 
8
+ static visitInProdMode() {
9
+ cy.visit('/login', {
10
+ onBeforeLoad: (win) => {
11
+ EnvironmentStubs.stubWbProdMode();
12
+ }
13
+ });
14
+ }
15
+
6
16
  static loginWithUser(username, password) {
17
+ cy.get('.login-form').should('be.visible');
7
18
  cy.get('#wb-login-username').type(username);
8
19
  cy.get('#wb-login-password').type(password);
9
20
  cy.get('#wb-login-submitLogin').click();
@@ -1,7 +1,7 @@
1
1
  export class MainMenuSteps {
2
2
 
3
3
  static getMainMenu() {
4
- return cy.get('.navbar-component');
4
+ return cy.get('onto-navbar');
5
5
  }
6
6
 
7
7
  static openHomePage() {
@@ -12,12 +12,12 @@ export class MainMenuSteps {
12
12
  return MainMenuSteps.getMainMenu().find('.menu-element').contains(menuName);
13
13
  }
14
14
 
15
- static getMenuImport() {
16
- return MainMenuSteps.getMenuButton('Import');
15
+ static getSubMenuButtonByName(menuName) {
16
+ return MainMenuSteps.getMainMenu().find('.sub-menu-link').contains(menuName);
17
17
  }
18
18
 
19
- static getMenuExplore() {
20
- return MainMenuSteps.getMenuButton('Explore');
19
+ static getMenuImport() {
20
+ return MainMenuSteps.getMenuButton('Import');
21
21
  }
22
22
 
23
23
  static getMenuSparql() {
@@ -58,7 +58,7 @@ export class MainMenuSteps {
58
58
  // Forced it because some element as "Explore" for example has CSS pointer-events: none
59
59
  MainMenuSteps.getMenuButton(menuName).click({force: true});
60
60
  }
61
-
61
+
62
62
  static clickOnSubmenuTriggerElement(menuName) {
63
63
  MainMenuSteps.getMainMenu().find('.menu-element-root').contains(menuName).parent().click();
64
64
  }
@@ -253,4 +253,11 @@ export class MainMenuSteps {
253
253
  this.clickOnMenuLab();
254
254
  this.getSubMenuButton('sub-menu-ttyg').click();
255
255
  }
256
+
257
+ // --------------------------
258
+ // -- Explore menu --
259
+ // --------------------------
260
+ static getMenuExplore() {
261
+ return MainMenuSteps.getMainMenu().getByTestId('menu-explore');
262
+ }
256
263
  }
@@ -1,3 +1,5 @@
1
+ import {BrowserStubs} from "../stubs/browser-stubs";
2
+
1
3
  export class OperationsStatusesComponentSteps {
2
4
 
3
5
  static getOperationsStatusesComponent() {
@@ -13,15 +15,15 @@ export class OperationsStatusesComponentSteps {
13
15
  }
14
16
 
15
17
  static getQueriesOperationStatusHeaderElement() {
16
- return OperationsStatusesComponentSteps.getOperationStatusHeader('.icon-exchange');
18
+ return OperationsStatusesComponentSteps.getOperationStatusHeader('.fa-arrow-right-arrow-left');
17
19
  }
18
20
 
19
21
  static getBackupAndRestoreOperationStatusHeaderElement() {
20
- return OperationsStatusesComponentSteps.getOperationStatusHeader('.fa.fa-archive');
22
+ return OperationsStatusesComponentSteps.getOperationStatusHeader('.fa-archive');
21
23
  }
22
24
 
23
25
  static getClusterOperationStatusHeaderElement() {
24
- return OperationsStatusesComponentSteps.getOperationStatusHeader('.fa.fa-sitemap');
26
+ return OperationsStatusesComponentSteps.getOperationStatusHeader('.fa-sitemap');
25
27
  }
26
28
 
27
29
  static getOperationStatuses() {
@@ -31,11 +33,4 @@ export class OperationsStatusesComponentSteps {
31
33
  static openOperationStatusesDialog() {
32
34
  OperationsStatusesComponentSteps.getOperationsStatusesComponent().click();
33
35
  }
34
-
35
- static checkOperationElementUrl(expectedUrl, operationIndex = 0) {
36
- OperationsStatusesComponentSteps.getOperationStatuses().eq(operationIndex).then(($operationElement) => {
37
- expect($operationElement).to.have.attr('target', '_blank');
38
- expect($operationElement).to.have.attr('href', expectedUrl);
39
- });
40
- }
41
36
  }
@@ -0,0 +1,55 @@
1
+ import {BaseSteps} from "./base-steps";
2
+
3
+ export class RdfResourceSearchSteps extends BaseSteps {
4
+
5
+ static getComponent() {
6
+ return this.getByTestId('onto-rdf-search-component');
7
+ }
8
+
9
+ static getShowViewResourceMessageButton() {
10
+ return this.getByTestId('onto-show-view-resource-message');
11
+ }
12
+
13
+ static clickOnShowViewResourceMessageButton() {
14
+ this.getShowViewResourceMessageButton().click();
15
+ }
16
+
17
+ static getOpenButton() {
18
+ return this.getByTestId('onto-open-rdf-search-button');
19
+ }
20
+
21
+ static clickOnRDFResourceSearch() {
22
+ this.getOpenButton().click();
23
+ }
24
+
25
+ static getRDFResourceSearchInput() {
26
+ return this.getComponent().getByTestId('rdfSearchContext');
27
+ }
28
+
29
+ static getCloseButton() {
30
+ return this.getComponent().getByTestId('onto-rdf-resource-search-close-btn');
31
+ }
32
+
33
+ static getAutocompleteResults() {
34
+ return this.getComponent().getByTestId('onto-autocomplete-results');
35
+ }
36
+
37
+ static getAutocompleteSuggestionByPartialText(partialText) {
38
+ return this.getAutocompleteResults().getByTestId('onto-autocomplete-suggestion').contains(partialText);
39
+ }
40
+
41
+ static clickOnAutocompleteSuggestionByPartialText(partialText) {
42
+ return this.getAutocompleteSuggestionByPartialText(partialText).click();
43
+ }
44
+
45
+ static openRdfSearchBox() {
46
+ RdfResourceSearchSteps.clickOnRDFResourceSearch();
47
+ RdfResourceSearchSteps.getRDFResourceSearchInput()
48
+ .should('be.visible')
49
+ .and('be.focused');
50
+ }
51
+
52
+ static closeRDFSearchBox() {
53
+ this.getCloseButton().click();
54
+ }
55
+ }
@@ -206,6 +206,7 @@ export class RepositorySteps {
206
206
  static selectRepoFromDropdown(repositoryId) {
207
207
  RepositorySteps.getRepositoriesDropdown().click();
208
208
  RepositorySteps.getRepositoriesInDropdown()
209
+ .should('be.visible')
209
210
  .contains(repositoryId)
210
211
  .first()
211
212
  .click();
@@ -83,6 +83,10 @@ export class AutocompleteSteps extends BaseSteps {
83
83
  return this.getAutocompletePage().find('#wb-autocomplete-labels');
84
84
  }
85
85
 
86
+ static getLabelRows() {
87
+ return this.getAutocompleteLabels().find('.wb-autocomplete-labels-row')
88
+ }
89
+
86
90
  static getTableRows() {
87
91
  return cy.get('.wb-autocomplete-labels-row');
88
92
  }
@@ -1,8 +1,26 @@
1
+ import {EnvironmentStubs} from "../../stubs/environment-stubs";
2
+
1
3
  export class SettingsSteps {
2
4
  static visit() {
3
5
  cy.visit('/settings');
4
6
  }
5
7
 
8
+ static visitInProdMode() {
9
+ cy.visit('/settings', {
10
+ onBeforeLoad: (win) => {
11
+ EnvironmentStubs.stubWbProdMode();
12
+ }
13
+ });
14
+ }
15
+
16
+ static visitInDevMode() {
17
+ cy.visit('/settings', {
18
+ onBeforeLoad: (win) => {
19
+ EnvironmentStubs.stubWbDevMode();
20
+ }
21
+ });
22
+ }
23
+
6
24
  static getSettingsPage() {
7
25
  return cy.get('#wb-user');
8
26
  }
@@ -1,8 +1,18 @@
1
+ import {EnvironmentStubs} from "../../stubs/environment-stubs";
2
+
1
3
  export class UserAndAccessSteps {
2
4
  static visit() {
3
5
  cy.visit('/users');
4
6
  }
5
7
 
8
+ static visitInProdMode() {
9
+ cy.visit('/users', {
10
+ onBeforeLoad: (win) => {
11
+ EnvironmentStubs.stubWbProdMode();
12
+ }
13
+ });
14
+ }
15
+
6
16
  static getUrl() {
7
17
  return cy.url();
8
18
  }
@@ -155,8 +165,20 @@ export class UserAndAccessSteps {
155
165
  cy.get('.write').click();
156
166
  }
157
167
 
158
- static getFieldError() {
159
- return cy.get('div.small');
168
+ static getCustomRoleFieldError() {
169
+ return cy.get('#user-custom-roles').find('small');
170
+ }
171
+
172
+ /**
173
+ * Returns the feedback <div> for the given login field error.
174
+ * @param field One of "username", "password", "confirmPassword"
175
+ */
176
+ static getUserFieldError(field) {
177
+ return cy.get(`.login-credentials [ng-show="${field}Error"].form-control-feedback`);
178
+ }
179
+
180
+ static getRepositoryRightsError() {
181
+ return cy.get('#user-repos [ng-show="repositoryCheckError"].form-control-feedback');
160
182
  }
161
183
 
162
184
  static getError() {
@@ -37,6 +37,30 @@ export class TtygAgentSettingsModalSteps extends ModalDialogSteps {
37
37
  return this.getAgentNameFormGroup().find('.alert-danger');
38
38
  }
39
39
 
40
+ static getExtIntegrationConfigBtn() {
41
+ return cy.get('.external-config-btn');
42
+ }
43
+
44
+ static openExtIntegrationConfig() {
45
+ this.getExtIntegrationConfigBtn().click();
46
+ }
47
+
48
+ static getExternalIntegrationModal() {
49
+ return cy.get('.external-integration-configuration-modal .modal-content');
50
+ }
51
+
52
+ static getAgentUrlField() {
53
+ return this.getExternalIntegrationModal().find('#agentId');
54
+ }
55
+
56
+ static getMethodUrlField() {
57
+ return this.getExternalIntegrationModal().find('#queryMethods');
58
+ }
59
+
60
+ static getDifyUrlField() {
61
+ return this.getExternalIntegrationModal().find('#difyExtension');
62
+ }
63
+
40
64
  // Repository ID
41
65
 
42
66
  static getRepositoryIdFromGroup() {
@@ -321,27 +345,62 @@ export class TtygAgentSettingsModalSteps extends ModalDialogSteps {
321
345
  this.getRetrievalConnectorField().find('option:selected').should('have.text', connectorName);
322
346
  }
323
347
 
324
- // GPT model
348
+ // LLM model
325
349
 
326
- static getGptModelFormGroup() {
327
- return this.getDialog().find('.gpt-model');
350
+ static getLLMModelFormGroup() {
351
+ return this.getDialog().find('.llm-model');
328
352
  }
329
353
 
330
- static getGptModelField() {
331
- return this.getGptModelFormGroup().find('input');
354
+ static getLLMModelField() {
355
+ return this.getLLMModelFormGroup().find('input');
332
356
  }
333
357
 
334
- static clearGptModel() {
335
- this.getGptModelField().clear();
358
+ static clearLLMModel() {
359
+ this.getLLMModelField().clear();
336
360
  cy.realPress('Tab');
337
361
  }
338
362
 
339
- static getGptModelError() {
340
- return this.getGptModelFormGroup().find('.alert-danger');
363
+ static getLLMModelError() {
364
+ return this.getLLMModelFormGroup().find('.alert-danger');
365
+ }
366
+
367
+ static typeLLMModel(value) {
368
+ return this.getLLMModelField().type(value);
369
+ }
370
+
371
+ static clickLLMModelField() {
372
+ this.getLLMModelField().click();
373
+ }
374
+
375
+ // Context size
376
+
377
+ static getContextSizeFormGroup() {
378
+ return this.getDialog().find('.context-size');
379
+ }
380
+
381
+ static getContextSizeField() {
382
+ return this.getDialog().find('.context-size input');
383
+ }
384
+
385
+ static clearContextSize() {
386
+ return this.getContextSizeField().clear();
341
387
  }
342
388
 
343
- static typeGptModel(value) {
344
- return this.getGptModelField().type(value);
389
+ static enterContextSize(input) {
390
+ this.getContextSizeField().type(input);
391
+ }
392
+
393
+ static getContextSizeError() {
394
+ return this.getContextSizeFormGroup().find('.alert-danger');
395
+ }
396
+
397
+ static resetContextSizeValue() {
398
+ this.getContextSizeField()
399
+ .realHover()
400
+ .then(() => this.getContextSizeFormGroup().find('.reset-context-size-btn'))
401
+ .scrollIntoView()
402
+ .should('be.visible')
403
+ .click();
345
404
  }
346
405
 
347
406
  // temperature
@@ -366,6 +425,10 @@ export class TtygAgentSettingsModalSteps extends ModalDialogSteps {
366
425
  return this.getTemperatureFormGroup().find('.high-temperature-warning');
367
426
  }
368
427
 
428
+ static scrollToTemperatureWarning() {
429
+ return this.getTemperatureWarning().scrollIntoView();
430
+ }
431
+
369
432
  // Top P
370
433
 
371
434
  static getTopPFormGroup() {
@@ -124,6 +124,13 @@ export class TTYGViewSteps extends BaseSteps {
124
124
  return this.getToggleChatsSidebarButton().click();
125
125
  }
126
126
 
127
+ static openAgentSettingsModalForAgent(index) {
128
+ TTYGViewSteps.expandAgentsSidebar();
129
+ TTYGViewSteps.openAgentsMenu();
130
+ TTYGViewSteps.selectAgent(index);
131
+ TTYGViewSteps.editCurrentAgent();
132
+ }
133
+
127
134
  static getCreateChatButton() {
128
135
  return this.getChatsSidebar().find('.create-chat-btn');
129
136
  }
@@ -235,12 +242,12 @@ export class TTYGViewSteps extends BaseSteps {
235
242
  return this.getAgent(index).realHover().find('.open-agent-actions-btn');
236
243
  }
237
244
 
238
- static openAgentActionMenu(index) {
245
+ static toggleAgentActionMenu(index) {
239
246
  this.getOpenAgentActionsButton(index).click();
240
247
  }
241
248
 
242
249
  static triggerEditAgentActionMenu(index) {
243
- this.openAgentActionMenu(index);
250
+ this.toggleAgentActionMenu(index);
244
251
  this.getEditAgentButton(index).click();
245
252
  }
246
253
 
@@ -248,8 +255,16 @@ export class TTYGViewSteps extends BaseSteps {
248
255
  return this.getAgent(index).find('.agent-actions-menu .edit-agent-btn');
249
256
  }
250
257
 
258
+ static getExternalIntegrationConfigButton(index) {
259
+ return this.getAgent(index).find('.agent-actions-menu .ext-integration-agent-btn');
260
+ }
261
+
262
+ static openExternalIntegrationConfigButton(index) {
263
+ return this.getExternalIntegrationConfigButton(index).click();
264
+ }
265
+
251
266
  static triggerCloneAgentActionMenu(index) {
252
- this.openAgentActionMenu(index);
267
+ this.toggleAgentActionMenu(index);
253
268
  this.getCloneAgentButton(index).click();
254
269
  }
255
270
 
@@ -258,7 +273,7 @@ export class TTYGViewSteps extends BaseSteps {
258
273
  }
259
274
 
260
275
  static triggerDeleteAgentActionMenu(index) {
261
- this.openAgentActionMenu(index);
276
+ this.toggleAgentActionMenu(index);
262
277
  this.getDeleteAgentButton(index).click();
263
278
  }
264
279
 
@@ -22,4 +22,8 @@ export class ActiveRepositoryWidgetSteps {
22
22
  static getInferredStatements() {
23
23
  return this.getWidget().find('.inferred-statements .data-value');
24
24
  }
25
+
26
+ static getImportLink() {
27
+ return this.getWidget().find('a.btn-link[href="import"]');
28
+ }
25
29
  }