diff --git a/ui/admin/app/components/form/storage-bucket/aws/index.hbs b/ui/admin/app/components/form/storage-bucket/aws/index.hbs index a4f53c64a..ccb7c6feb 100644 --- a/ui/admin/app/components/form/storage-bucket/aws/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/aws/index.hbs @@ -26,7 +26,7 @@ {{#if @model.errors.name}} {{#each @model.errors.name as |error|}} - {{error.message}} + {{error.message}} {{/each}} {{/if}} diff --git a/ui/admin/app/components/form/storage-bucket/minio/index.hbs b/ui/admin/app/components/form/storage-bucket/minio/index.hbs index f63b30ee7..452a6de6e 100644 --- a/ui/admin/app/components/form/storage-bucket/minio/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/minio/index.hbs @@ -26,7 +26,7 @@ {{#if @model.errors.name}} {{#each @model.errors.name as |error|}} - {{error.message}} + {{error.message}} {{/each}} {{/if}} diff --git a/ui/admin/tests/acceptance/targets/enable-session-recording/create-storage-bucket-test.js b/ui/admin/tests/acceptance/targets/enable-session-recording/create-storage-bucket-test.js index 0ca84d7d8..5ba8f1276 100644 --- a/ui/admin/tests/acceptance/targets/enable-session-recording/create-storage-bucket-test.js +++ b/ui/admin/tests/acceptance/targets/enable-session-recording/create-storage-bucket-test.js @@ -21,16 +21,11 @@ module( let features; let getStorageBucketCount; - const SAVE_BTN_SELECTOR = '[type="submit"]'; - const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]'; - const NAME_FIELD_SELECTOR = '[name="name"]'; - const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message'; - const NAME_FIELD_TEXT = 'random string'; - const BUCKET_NAME_FIELD_SELECTOR = '[name="bucket_name"]'; - const BUCKET_PREFIX_FIELD_SELECTOR = '[name="bucket_prefix"]'; - const EDITOR_WORKER_FILTER = - '[data-test-code-editor-field-editor] textarea'; - const EDITOR_WORKER_FILTER_VALUE = '"dev" in "/tags/env"'; + const FIELD_BUCKET_NAME = '[name="bucket_name"]'; + const FIELD_BUCKET_PREFIX = '[name="bucket_prefix"]'; + const FIELD_EDITOR = '[data-test-code-editor-field-editor] textarea'; + const WORKER_FILTER_VALUE = '"dev" in "/tags/env"'; + const FIELD_SCOPE = (scope) => `[value="${scope}"]`; const instances = { scopes: { @@ -40,8 +35,6 @@ module( }; const urls = { - globalScope: null, - projectScope: null, targets: null, target: null, enableSessionRecording: null, @@ -63,10 +56,8 @@ module( scope: instances.scopes.project, type: TYPE_TARGET_SSH, }); - urls.globalScope = `/scopes/global`; - urls.projectScope = `/scopes/${instances.scopes.project.id}`; - urls.targets = `${urls.projectScope}/targets`; + urls.targets = `/scopes/${instances.scopes.project.id}/targets`; urls.target = `${urls.targets}/${instances.target.id}`; urls.enableSessionRecording = `${urls.target}/enable-session-recording`; urls.newStorageBucket = `${urls.enableSessionRecording}/create-storage-bucket`; @@ -82,22 +73,25 @@ module( const storageBucketCount = getStorageBucketCount(); await visit(urls.enableSessionRecording); - await click(`[href="${urls.newStorageBucket}"]`); - await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); - await click('[value="global"]'); - await fillIn(EDITOR_WORKER_FILTER, EDITOR_WORKER_FILTER_VALUE); + await click(commonSelectors.HREF(urls.newStorageBucket)); + await fillIn( + commonSelectors.FIELD_NAME, + commonSelectors.FIELD_NAME_VALUE, + ); + await click(FIELD_SCOPE('global')); + await fillIn(FIELD_EDITOR, WORKER_FILTER_VALUE); - assert.dom(BUCKET_NAME_FIELD_SELECTOR).isNotDisabled(); - assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isNotDisabled(); - assert.dom(BUCKET_NAME_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); - assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); + assert.dom(FIELD_BUCKET_NAME).isNotDisabled(); + assert.dom(FIELD_BUCKET_PREFIX).isNotDisabled(); + assert.dom(FIELD_BUCKET_NAME).doesNotHaveAttribute('readOnly'); + assert.dom(FIELD_BUCKET_PREFIX).doesNotHaveAttribute('readOnly'); - await click(SAVE_BTN_SELECTOR); + await click(commonSelectors.SAVE_BTN); const storageBucket = this.server.schema.storageBuckets.findBy({ - name: NAME_FIELD_TEXT, + name: commonSelectors.FIELD_NAME_VALUE, }); - assert.strictEqual(storageBucket.name, NAME_FIELD_TEXT); + assert.strictEqual(storageBucket.name, commonSelectors.FIELD_NAME_VALUE); assert.strictEqual(storageBucket.scopeId, 'global'); assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1); }); @@ -106,22 +100,25 @@ module( const storageBucketCount = getStorageBucketCount(); await visit(urls.enableSessionRecording); - await click(`[href="${urls.newStorageBucket}"]`); - await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); - await click(`[value="${instances.scopes.org.scope.id}"]`); - await fillIn(EDITOR_WORKER_FILTER, EDITOR_WORKER_FILTER_VALUE); + await click(commonSelectors.HREF(urls.newStorageBucket)); + await fillIn( + commonSelectors.FIELD_NAME, + commonSelectors.FIELD_NAME_VALUE, + ); + await click(FIELD_SCOPE(instances.scopes.org.scope.id)); + await fillIn(FIELD_EDITOR, WORKER_FILTER_VALUE); - assert.dom(BUCKET_NAME_FIELD_SELECTOR).isNotDisabled(); - assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isNotDisabled(); - assert.dom(BUCKET_NAME_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); - assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).doesNotHaveAttribute('readOnly'); + assert.dom(FIELD_BUCKET_NAME).isNotDisabled(); + assert.dom(FIELD_BUCKET_PREFIX).isNotDisabled(); + assert.dom(FIELD_BUCKET_NAME).doesNotHaveAttribute('readOnly'); + assert.dom(FIELD_BUCKET_PREFIX).doesNotHaveAttribute('readOnly'); - await click(SAVE_BTN_SELECTOR); + await click(commonSelectors.SAVE_BTN); const storageBucket = this.server.schema.storageBuckets.findBy({ - name: NAME_FIELD_TEXT, + name: commonSelectors.FIELD_NAME_VALUE, }); - assert.strictEqual(storageBucket.name, NAME_FIELD_TEXT); + assert.strictEqual(storageBucket.name, commonSelectors.FIELD_NAME_VALUE); assert.strictEqual(storageBucket.scopeId, instances.scopes.org.scope.id); assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1); }); @@ -130,15 +127,20 @@ module( const storageBucketCount = getStorageBucketCount(); await visit(urls.enableSessionRecording); - await click(`[href="${urls.newStorageBucket}"]`); - await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT); - await click(CANCEL_BTN_SELECTOR); + await click(commonSelectors.HREF(urls.newStorageBucket)); + await fillIn( + commonSelectors.FIELD_NAME, + commonSelectors.FIELD_NAME_VALUE, + ); + await click(commonSelectors.CANCEL_BTN); assert.strictEqual(currentURL(), urls.enableSessionRecording); assert.strictEqual(getStorageBucketCount(), storageBucketCount); }); test('saving a new storage bucket with invalid fields displays error messages', async function (assert) { + const errorMessage = 'The request was invalid.'; + const errorDescription = 'Name is required.'; this.server.post('/storage-buckets', () => { return new Response( 400, @@ -146,12 +148,12 @@ module( { status: 400, code: 'invalid_argument', - message: 'The request was invalid.', + message: errorMessage, details: { request_fields: [ { name: 'name', - description: 'Name is required.', + description: errorDescription, }, ], }, @@ -160,14 +162,12 @@ module( }); await visit(urls.enableSessionRecording); - await click(`[href="${urls.newStorageBucket}"]`); - await fillIn(EDITOR_WORKER_FILTER, EDITOR_WORKER_FILTER_VALUE); - await click(SAVE_BTN_SELECTOR); + await click(commonSelectors.HREF(urls.newStorageBucket)); + await fillIn(FIELD_EDITOR, WORKER_FILTER_VALUE); + await click(commonSelectors.SAVE_BTN); - assert - .dom(commonSelectors.ALERT_TOAST_BODY) - .hasText('The request was invalid.'); - assert.dom(FIELD_ERROR_TEXT_SELECTOR).hasText('Name is required.'); + assert.dom(commonSelectors.ALERT_TOAST_BODY).hasText(errorMessage); + assert.dom(commonSelectors.FIELD_NAME_ERROR).hasText(errorDescription); }); }, ); diff --git a/ui/admin/tests/acceptance/targets/enable-session-recording/index-test.js b/ui/admin/tests/acceptance/targets/enable-session-recording/index-test.js index c42520dcc..aef7ed499 100644 --- a/ui/admin/tests/acceptance/targets/enable-session-recording/index-test.js +++ b/ui/admin/tests/acceptance/targets/enable-session-recording/index-test.js @@ -11,6 +11,8 @@ import a11yAudit from 'ember-a11y-testing/test-support/audit'; import { authenticateSession } from 'ember-simple-auth/test-support'; import { TYPE_TARGET_SSH } from 'api/models/target'; import select from '@ember/test-helpers/dom/select'; +import * as commonSelectors from 'admin/tests/helpers/selectors'; +import * as selectors from '../selectors'; module( 'Acceptance | targets | enable session recording | index', @@ -22,17 +24,13 @@ module( let storageBucketOne; let storageBucketTwo; - const SETTINGS_LINK_SELECTOR = '.target-sidebar .hds-link-standalone'; - const ENABLE_BUTTON_SELECTOR = '.target-sidebar .hds-button'; - const DROPDOWN_SELECTOR = '[name=storage_bucket_id]'; - const LINK_LIST_SELECTOR = '.link-list-item > a'; - const LINK_LIST_SELECTOR_ITEM_TEXT = '.link-list-item__text'; - const BADGE_TEXT_SELECTOR = '.target-sidebar .hds-badge__text'; - const TOGGLE_SELECTOR = '[name=target-enable-session-recording]'; + const SESSION_RECORDING_SETTINGS_LINK = + '.target-sidebar .hds-link-standalone'; + const SESSION_RECORDING_ENABLE_BTN = '.target-sidebar .hds-button'; + const ENABLE_TOGGLE = '[name=target-enable-session-recording]'; + const BADGE_TEXT = '.target-sidebar .hds-badge__text'; const LINK_TO_NEW_STORAGE_BUCKET = '.enable-session-recording-toggle .hds-link-standalone'; - const SAVE_BTN_SELECTOR = '.rose-form-actions [type="submit"]'; - const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]'; // Instances const instances = { @@ -45,9 +43,6 @@ module( //URLs const urls = { - globalScope: null, - orgScope: null, - projectScope: null, targets: null, target: null, enableSessionRecording: null, @@ -82,13 +77,10 @@ module( storageBucketTwo = instances.storageBucket[1]; // Generate route URLs for resources - urls.globalScope = `/scopes/global`; - urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; - urls.projectScope = `/scopes/${instances.scopes.project.id}`; - urls.targets = `${urls.projectScope}/targets`; + urls.targets = `/scopes/${instances.scopes.project.id}/targets`; urls.target = `${urls.targets}/${instances.target.id}`; urls.enableSessionRecording = `${urls.target}/enable-session-recording`; - urls.storageBuckets = `${urls.globalScope}/storage-buckets`; + urls.storageBuckets = '/scopes/global/storage-buckets'; urls.newStorageBucket = `${urls.enableSessionRecording}/create-storage-bucket`; urls.storageBucket = `${urls.storageBuckets}/${storageBucketOne.id}`; @@ -99,16 +91,21 @@ module( test('cannot enable session recording for a target without proper authorization', async function (assert) { assert.false(featuresService.isEnabled('ssh-session-recording')); + await visit(urls.target); await a11yAudit(); - assert.dom('.target-sidebar a').doesNotExist(); + + assert.dom(SESSION_RECORDING_ENABLE_BTN).doesNotExist(); }); test('users can click on enable-recording button in target session-recording sidebar and it takes them to enable session recording', async function (assert) { featuresService.enable('ssh-session-recording'); await visit(urls.target); - assert.dom(SETTINGS_LINK_SELECTOR).doesNotExist(); - await click(ENABLE_BUTTON_SELECTOR); + + assert.dom(SESSION_RECORDING_SETTINGS_LINK).doesNotExist(); + + await click(SESSION_RECORDING_ENABLE_BTN); + assert.strictEqual(currentURL(), urls.enableSessionRecording); }); @@ -119,7 +116,8 @@ module( enableSessionRecording: true, }); await visit(urls.target); - await click(SETTINGS_LINK_SELECTOR); + await click(SESSION_RECORDING_SETTINGS_LINK); + assert.strictEqual(currentURL(), urls.enableSessionRecording); }); @@ -130,37 +128,45 @@ module( enableSessionRecording: true, }); await visit(urls.target); - await click(LINK_LIST_SELECTOR); + await click(selectors.LINK_LIST_ITEM); + assert.strictEqual(currentURL(), urls.storageBucket); }); test('toggle should be disabled and storage buckets list should be shown when enable session recording button is clicked', async function (assert) { featuresService.enable('ssh-session-recording'); await visit(urls.target); - await click(ENABLE_BUTTON_SELECTOR); + await click(SESSION_RECORDING_ENABLE_BTN); + assert.strictEqual(currentURL(), urls.enableSessionRecording); - assert.dom(TOGGLE_SELECTOR).isVisible(); - assert.dom(DROPDOWN_SELECTOR).isNotVisible(); + assert.dom(ENABLE_TOGGLE).isVisible(); + assert.dom(selectors.STORAGE_BUCKET_DROPDOWN).isNotVisible(); }); test('storage buckets list is hidden when toggle is disabled', async function (assert) { featuresService.enable('ssh-session-recording'); await visit(urls.target); - await click(ENABLE_BUTTON_SELECTOR); + await click(SESSION_RECORDING_ENABLE_BTN); + assert.strictEqual(currentURL(), urls.enableSessionRecording); - assert.dom(TOGGLE_SELECTOR).isVisible(); - assert.dom(DROPDOWN_SELECTOR).isNotVisible(); - await click(TOGGLE_SELECTOR); - assert.dom(DROPDOWN_SELECTOR).isVisible(); + assert.dom(ENABLE_TOGGLE).isVisible(); + assert.dom(selectors.STORAGE_BUCKET_DROPDOWN).isNotVisible(); + + await click(ENABLE_TOGGLE); + + assert.dom(selectors.STORAGE_BUCKET_DROPDOWN).isVisible(); }); test('link to add new storage bucket should be displayed and redirect to new storage buckets form', async function (assert) { featuresService.enable('ssh-session-recording'); await visit(urls.target); - await click(ENABLE_BUTTON_SELECTOR); + await click(SESSION_RECORDING_ENABLE_BTN); + assert.strictEqual(currentURL(), urls.enableSessionRecording); assert.dom(LINK_TO_NEW_STORAGE_BUCKET).isVisible(); + await click(LINK_TO_NEW_STORAGE_BUCKET); + assert.strictEqual(currentURL(), urls.newStorageBucket); }); @@ -171,45 +177,54 @@ module( enable_session_recording: true, }); await visit(urls.target); - await click(SETTINGS_LINK_SELECTOR); + await click(SESSION_RECORDING_SETTINGS_LINK); + assert.strictEqual(currentURL(), urls.enableSessionRecording); - const existingStorageBucketId = find(DROPDOWN_SELECTOR).value; + const existingStorageBucketId = find( + selectors.STORAGE_BUCKET_DROPDOWN, + ).value; //disable the toggle, dropdown should be hidden - await click(TOGGLE_SELECTOR); - assert.dom(DROPDOWN_SELECTOR).isNotVisible(); + await click(ENABLE_TOGGLE); + + assert.dom(selectors.STORAGE_BUCKET_DROPDOWN).isNotVisible(); //enable the toggle now, //it should have the previously selected storage_bucket_id - await click(TOGGLE_SELECTOR); - assert.dom(DROPDOWN_SELECTOR).hasValue(existingStorageBucketId); + await click(ENABLE_TOGGLE); + + assert + .dom(selectors.STORAGE_BUCKET_DROPDOWN) + .hasValue(existingStorageBucketId); }); test('can assign a storage bucket for the target', async function (assert) { featuresService.enable('ssh-session-recording'); await visit(urls.target); - await click(ENABLE_BUTTON_SELECTOR); + await click(SESSION_RECORDING_ENABLE_BTN); assert.strictEqual(currentURL(), urls.enableSessionRecording); - await click(TOGGLE_SELECTOR); - assert.dom(DROPDOWN_SELECTOR).hasNoValue(); - await select(DROPDOWN_SELECTOR, storageBucketTwo.id); - assert.dom(DROPDOWN_SELECTOR).hasValue(); - await click(SAVE_BTN_SELECTOR); + + await click(ENABLE_TOGGLE); + + assert.dom(selectors.STORAGE_BUCKET_DROPDOWN).hasNoValue(); + + await select(selectors.STORAGE_BUCKET_DROPDOWN, storageBucketTwo.id); + + assert.dom(selectors.STORAGE_BUCKET_DROPDOWN).hasValue(); + + await click(commonSelectors.SAVE_BTN); assert.strictEqual(currentURL(), urls.target); - assert.strictEqual( - find(BADGE_TEXT_SELECTOR).textContent.trim(), - intl.t( - `resources.storage-bucket.plugin-types.${storageBucketTwo.plugin.name}`, - ), - ); - - assert.strictEqual( - find(LINK_LIST_SELECTOR_ITEM_TEXT).textContent.trim(), - storageBucketTwo.name, - ); + assert + .dom(BADGE_TEXT) + .hasText( + intl.t( + `resources.storage-bucket.plugin-types.${storageBucketTwo.plugin.name}`, + ), + ); + assert.dom(selectors.LINK_LIST_ITEM_TEXT).hasText(storageBucketTwo.name); }); test('can cancel changes to an existing storage bucket selection', async function (assert) { @@ -220,25 +235,23 @@ module( }); await visit(urls.target); - await click(SETTINGS_LINK_SELECTOR); + await click(SESSION_RECORDING_SETTINGS_LINK); + assert.strictEqual(currentURL(), urls.enableSessionRecording); //update the storage bucket selection - await select(DROPDOWN_SELECTOR, storageBucketTwo); + await select(selectors.STORAGE_BUCKET_DROPDOWN, storageBucketTwo); + await click(commonSelectors.CANCEL_BTN); - await click(CANCEL_BTN_SELECTOR); assert.strictEqual(currentURL(), urls.target); - assert.strictEqual( - find(BADGE_TEXT_SELECTOR).textContent.trim(), - intl.t( - `resources.storage-bucket.plugin-types.${storageBucketOne.plugin.name}`, - ), - ); - - assert.strictEqual( - find(LINK_LIST_SELECTOR_ITEM_TEXT).textContent.trim(), - storageBucketOne.name, - ); + assert + .dom(BADGE_TEXT) + .hasText( + intl.t( + `resources.storage-bucket.plugin-types.${storageBucketOne.plugin.name}`, + ), + ); + assert.dom(selectors.LINK_LIST_ITEM_TEXT).hasText(storageBucketOne.name); }); }, ); diff --git a/ui/admin/tests/acceptance/targets/selectors.js b/ui/admin/tests/acceptance/targets/selectors.js index e986a7121..60f299ddb 100644 --- a/ui/admin/tests/acceptance/targets/selectors.js +++ b/ui/admin/tests/acceptance/targets/selectors.js @@ -49,6 +49,8 @@ export const RECORDING_SETTINGS_LINK = '.target-sidebar .hds-link-standalone'; export const LINK_LIST_ITEM = '.link-list-item > a'; export const LINK_LIST_ITEM_TEXT = '.link-list-item__text'; +export const STORAGE_BUCKET_DROPDOWN = '[name=storage_bucket_id]'; + export const NO_RESULTS_MSG = '[data-test-no-target-results]'; export const TABLE_ACTIVE_SESSIONS = (id) => `tbody [data-test-targets-table-row="${id}"] .hds-table__td:nth-child(3) a`;