diff --git a/ui/lib/core/addon/components/form-field.hbs b/ui/lib/core/addon/components/form-field.hbs index 6dd6d85d39..b494632128 100644 --- a/ui/lib/core/addon/components/form-field.hbs +++ b/ui/lib/core/addon/components/form-field.hbs @@ -11,57 +11,58 @@ {{! •••••••••••••••••••••••••••••••••••••••••••••••••••••••• }} {{#if @attr.options.possibleValues}} {{#if (eq @attr.options.editType "checkboxList")}} - + {{#if this.labelString}} {{this.labelString}} {{/if}} {{#if this.helpTextString}} - {{this.helpTextString}} + {{this.helpTextString}} {{/if}} {{#if @attr.options.subText}} - + {{@attr.options.subText}} {{#if @attr.options.docLink}} - See our documentation + See our documentation for help. {{/if}} {{/if}} {{#each @attr.options.possibleValues as |option|}} - {{option}} + {{option}} {{/each}} {{#if this.validationError}} - {{this.validationError}} + {{this.validationError}} {{/if}} {{else}} {{#if this.labelString}} {{this.labelString}} {{/if}} {{#if this.helpTextString}} - {{this.helpTextString}} + {{this.helpTextString}} {{/if}} {{#if @attr.options.subText}} - + {{@attr.options.subText}} {{#if @attr.options.docLink}} - See our documentation + See our documentation for help. {{/if}} @@ -79,7 +80,7 @@ {{/each}} {{#if this.validationError}} - {{this.validationError}} + {{this.validationError}} {{/if}} {{/if}} @@ -88,12 +89,13 @@ {{#if (eq @attr.options.editType "password")}} {{this.labelString}} {{/if}} {{#if this.helpTextString}} - {{this.helpTextString}} + {{this.helpTextString}} {{/if}} {{#if @attr.options.subText}} - + {{@attr.options.subText}} {{#if @attr.options.docLink}} - See our documentation + See our + documentation for help. {{/if}} {{/if}} {{/unless}} {{#if this.validationError}} - {{this.validationError}} + {{this.validationError}} {{/if}} {{/if}} @@ -310,7 +313,7 @@ {{@attr.options.subText}} {{#if @attr.options.docLink}} - + See our documentation for help. @@ -320,7 +323,7 @@ {{or @attr.options.defaultSubText "Vault will use the engine default."}} {{#if @attr.options.docLink}} - + See our documentation for help. @@ -404,7 +407,7 @@

{{@attr.options.subText}} {{#if @attr.options.docLink}} - + See our documentation for help. @@ -451,7 +454,7 @@

{{@attr.options.subText}} {{#if @attr.options.docLink}} - + Learn more here. {{/if}} @@ -474,7 +477,7 @@ @type="danger" @message={{this.validationError}} @paddingTop={{not-eq @attr.options.editType "ttl"}} - data-test-field-validation={{this.valuePath}} + data-test-validation-error={{this.valuePath}} class={{if (eq @attr.options.editType "stringArray") "has-top-margin-negative-xxl"}} /> {{/if}} diff --git a/ui/lib/core/addon/components/form-field.js b/ui/lib/core/addon/components/form-field.js index 87d27ee041..93ffeea646 100644 --- a/ui/lib/core/addon/components/form-field.js +++ b/ui/lib/core/addon/components/form-field.js @@ -195,6 +195,16 @@ export default class FormFieldComponent extends Component { this.setAndBroadcast(valueToSet); } @action + setAndBroadcastChecklist(event) { + let updatedValue = this.args.model[this.valuePath]; + if (event.target.checked) { + updatedValue = addToArray(updatedValue, event.target.value); + } else { + updatedValue = removeFromArray(updatedValue, event.target.value); + } + this.setAndBroadcast(updatedValue); + } + @action setAndBroadcastTtl(value) { const alwaysSendValue = this.valuePath === 'expiry' || this.valuePath === 'safetyBuffer'; const attrOptions = this.args.attr.options || {}; @@ -243,15 +253,4 @@ export default class FormFieldComponent extends Component { const prop = event.target.type === 'checkbox' ? 'checked' : 'value'; this.setAndBroadcast(event.target[prop]); } - - @action - handleChecklist(event) { - let updatedValue = this.args.model[this.valuePath]; - if (event.target.checked) { - updatedValue = addToArray(updatedValue, event.target.value); - } else { - updatedValue = removeFromArray(updatedValue, event.target.value); - } - this.setAndBroadcast(updatedValue); - } } diff --git a/ui/lib/core/addon/components/text-file.hbs b/ui/lib/core/addon/components/text-file.hbs index 09625282c2..3fa58c49b8 100644 --- a/ui/lib/core/addon/components/text-file.hbs +++ b/ui/lib/core/addon/components/text-file.hbs @@ -80,7 +80,7 @@ @type="danger" @message={{or @validationError this.uploadError}} class="has-top-padding-s" - data-test-field-validation="text-file" + data-test-inline-alert /> {{/if}} {{/if}} diff --git a/ui/tests/helpers/config-ui/message-selectors.ts b/ui/tests/helpers/config-ui/message-selectors.ts index 7430ab71f1..7f3d63ced7 100644 --- a/ui/tests/helpers/config-ui/message-selectors.ts +++ b/ui/tests/helpers/config-ui/message-selectors.ts @@ -12,7 +12,7 @@ export const CUSTOM_MESSAGES = { field: (fieldName: string) => `[data-test-field="${fieldName}"]`, input: (input: string) => `[data-test-input="${input}"]`, button: (buttonName: string) => `[data-test-button="${buttonName}"]`, - fieldValidation: (fieldName: string) => `[data-test-field-validation="${fieldName}"]`, + fieldValidation: (fieldName: string) => `[data-test-validation-error="${fieldName}"]`, modal: (name: string) => `[data-test-modal="${name}"]`, modalTitle: (title: string) => `[data-test-modal-title="${title}"]`, modalBody: (name: string) => `[data-test-modal-body="${name}"]`, diff --git a/ui/tests/helpers/general-selectors.ts b/ui/tests/helpers/general-selectors.ts index 90fa999c9c..2ea6cccd4c 100644 --- a/ui/tests/helpers/general-selectors.ts +++ b/ui/tests/helpers/general-selectors.ts @@ -38,9 +38,20 @@ export const GENERAL = { listItem: '[data-test-list-item-link]', // FORMS checkboxByAttr: (attr: string) => `[data-test-checkbox="${attr}"]`, + docLinkByAttr: (attr: string) => `[data-test-doc-link="${attr}"]`, enableField: (attr: string) => `[data-test-enable-field="${attr}"] button`, fieldByAttr: (attr: string) => `[data-test-field="${attr}"]`, + fieldLabel: () => `[data-test-form-field-label]`, + fieldLabelbyAttr: (attr: string) => `[data-test-form-field-label="${attr}"]`, + helpText: () => `[data-test-help-text]`, + helpTextByAttr: (attr: string) => `[data-test-help-text="${attr}"]`, + helpTextByGroupControlIndex: (index: number) => + `.hds-form-group__control-field:nth-of-type(${index}) [data-test-help-text]`, inputByAttr: (attr: string) => `[data-test-input="${attr}"]`, + groupControlByIndex: (index: number) => `.hds-form-group__control-field:nth-of-type(${index})`, + inputGroupByAttr: (attr: string) => `[data-test-input-group="${attr}"]`, + labelById: (id: string) => `label[id="${id}"]`, + labelByGroupControlIndex: (index: number) => `.hds-form-group__control-field:nth-of-type(${index}) label`, selectByAttr: (attr: string) => `[data-test-select="${attr}"]`, textToggle: '[data-test-text-toggle]', textToggleTextarea: '[data-test-text-file-textarea]', @@ -54,8 +65,8 @@ export const GENERAL = { infoRowLabel: (label: string) => `[data-test-row-label="${label}"]`, infoRowValue: (label: string) => `[data-test-row-value="${label}"]`, // Validation - validation: (attr: string) => `[data-test-field-validation=${attr}]`, - validationWarning: (attr: string) => `[data-test-validation-warning=${attr}]`, + validationErrorByAttr: (attr: string) => `[data-test-validation-error=${attr}]`, + validationWarningByAttr: (attr: string) => `[data-test-validation-warning=${attr}]`, messageError: '[data-test-message-error]', notFound: '[data-test-not-found]', pageError: { diff --git a/ui/tests/helpers/sync/sync-selectors.js b/ui/tests/helpers/sync/sync-selectors.js index 61f4ee7616..25233e1791 100644 --- a/ui/tests/helpers/sync/sync-selectors.js +++ b/ui/tests/helpers/sync/sync-selectors.js @@ -100,9 +100,9 @@ export const PAGE = { await fillIn('[data-test-kv-key="0"]', 'foo'); return fillIn('[data-test-kv-value="0"]', value); case 'deploymentEnvironments': - await click('[data-test-input="deploymentEnvironments"] input#development'); - await click('[data-test-input="deploymentEnvironments"] input#preview'); - return await click('[data-test-input="deploymentEnvironments"] input#production'); + await click('[data-test-input-group="deploymentEnvironments"] input#development'); + await click('[data-test-input-group="deploymentEnvironments"] input#preview'); + return await click('[data-test-input-group="deploymentEnvironments"] input#production'); default: return fillIn(`[data-test-input="${attr}"]`, value); } diff --git a/ui/tests/integration/components/form-field-test.js b/ui/tests/integration/components/form-field-test.js index 09f57df3e7..cdfb4cdbd8 100644 --- a/ui/tests/integration/components/form-field-test.js +++ b/ui/tests/integration/components/form-field-test.js @@ -6,13 +6,15 @@ import EmberObject from '@ember/object'; import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render, click, fillIn } from '@ember/test-helpers'; +import { render, click, fillIn, findAll } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { create } from 'ember-cli-page-object'; import sinon from 'sinon'; import formFields from '../../pages/components/form-field'; import { format, startOfDay } from 'date-fns'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; + const component = create(formFields); module('Integration | Component | form field', function (hooks) { @@ -46,6 +48,10 @@ module('Integration | Component | form field', function (hooks) { assert.notOk(component.hasInput, 'renders only the label'); }); + // ------------------ + // LEGACY FORM FIELDS + // ------------------ + test('it renders: string', async function (assert) { const [model, spy] = await setup.call(this, createAttr('foo', 'string', { defaultValue: 'default' })); assert.strictEqual(component.fields.objectAt(0).labelValue, 'Foo', 'renders a label'); @@ -285,6 +291,8 @@ module('Integration | Component | form field', function (hooks) { assert.ok(spy.calledWith('password', 'secret'), 'onChange called with correct args'); }); + // --- common elements (legacy) --- + test('it uses a passed label', async function (assert) { await setup.call(this, createAttr('foo', 'string', { label: 'Not Foo' })); assert.strictEqual(component.fields.objectAt(0).labelValue, 'Not Foo', 'renders the label from options'); @@ -297,7 +305,7 @@ module('Integration | Component | form field', function (hooks) { ); await component.tooltipTrigger(); assert.ok(component.hasTooltip, 'renders the tooltip component'); - assert.dom('[data-test-input="foo"]').hasAttribute('placeholder', 'example::value'); + assert.dom(GENERAL.inputByAttr('foo')).hasAttribute('placeholder', 'example::value'); }); test('it should not expand and toggle ttl when default 0s value is present', async function (assert) { @@ -343,6 +351,337 @@ module('Integration | Component | form field', function (hooks) { await render( hbs`` ); - assert.dom('[data-test-validation-warning]').exists('Validation warning renders'); + assert.dom(GENERAL.validationWarningByAttr('path')).exists('Validation warning renders'); + }); + + // --------------- + // HDS FORM FIELDS + // --------------- + // Note: some tests may be duplicative of the generic tests above + // + + // ––––– editType === 'checkboxList' / possibleValues ––––– + + test('it renders: editType=checkboxList / possibleValues - as Hds::Form::Checkbox::Group', async function (assert) { + const possibleValues = ['foo', 'bar', 'baz']; + await setup.call(this, createAttr('myfield', '-', { editType: 'checkboxList', possibleValues })); + const labels = findAll(`${GENERAL.inputGroupByAttr('myfield')} label`); + const inputs = findAll(`${GENERAL.inputGroupByAttr('myfield')} input[type="checkbox"]`); + assert + .dom('.field [class^="hds-form-group"] input[type="checkbox"].hds-form-checkbox') + .exists('renders as Hds::Form::Checkbox::Group'); + assert.strictEqual(inputs.length, 3, 'renders a fieldset element with 3 checkbox elements'); + assert.dom(GENERAL.fieldLabel()).hasText('Myfield', 'renders the input group label'); + possibleValues.forEach((possibleValue, index) => { + assert + .dom(labels[index]) + .hasAttribute('id', `label-${possibleValue}`, 'label has correct id') + .hasText(possibleValue, 'label has correct text'); + assert + .dom(inputs[index]) + .hasAttribute('id', possibleValue, 'input[type="checkbox"] has correct id') + .hasAttribute( + 'data-test-checkbox', + possibleValue, + 'input[type="checkbox"] has correct `data-test-checkbox` attribute' + ); + }); + }); + + test('it renders: editType=checkboxList / possibleValues - with no selected checkbox', async function (assert) { + const possibleValues = ['foo', 'bar', 'baz']; + await setup.call(this, createAttr('myfield', '-', { editType: 'checkboxList', possibleValues })); + possibleValues.forEach((possibleValue) => { + assert + .dom(GENERAL.checkboxByAttr(possibleValue)) + .isNotChecked(`input[type="checkbox"] "${possibleValue}" is not checked`); + }); + }); + + test('it renders: editType=checkboxList / possibleValues - with selected value and changes it', async function (assert) { + const [model, spy] = await setup.call( + this, + createAttr('myfield', '-', { + editType: 'checkboxList', + possibleValues: ['foo', 'bar', 'baz'], + defaultValue: ['baz'], + }) + ); + assert.dom(GENERAL.checkboxByAttr('baz')).isChecked('input[type="checkbox"] "baz" is checked'); + // select the remaining items (they're appended to the model) + await click(GENERAL.checkboxByAttr('foo')); + await click(GENERAL.checkboxByAttr('bar')); + // notice: we can't use `strictEqual` here because they're different objects + assert.deepEqual(model.get('myfield'), ['baz', 'foo', 'bar']); + assert.ok(spy.calledWith('myfield', ['baz', 'foo', 'bar']), 'onChange called with correct args'); + }); + + test('it renders: editType=checkboxList / possibleValues - with passed label, subtext, helptext, doclink', async function (assert) { + await setup.call( + this, + createAttr('myfield', '-', { + editType: 'checkboxList', + possibleValues: ['foo', 'bar', 'baz'], + label: 'Custom label', + subText: 'Some subtext', + helpText: 'Some helptext', + docLink: '/docs', + }) + ); + assert.dom(GENERAL.fieldLabel()).hasText('Custom label', 'renders the custom label from options'); + assert + .dom(GENERAL.helpTextByAttr('Some subtext')) + .exists('renders `subText` option as HelperText') + .hasText( + 'Some subtext See our documentation for help.', + 'renders the right subtext string from options' + ); + assert + .dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`) + .exists('renders `docLink` option as as link inside the subtext'); + assert + .dom(GENERAL.helpTextByAttr('Some helptext')) + .exists('renders `helptext` option as HelperText') + .hasText('Some helptext', 'renders the right help text string from options'); + }); + + test('it renders: editType=checkboxList / possibleValues - with validation errors and warnings', async function (assert) { + this.setProperties({ + attr: createAttr('myfield', '-', { editType: 'checkboxList', possibleValues: ['foo', 'bar', 'baz'] }), + model: { myfield: 'bar' }, + modelValidations: { + myfield: { + isValid: false, + errors: ['Error message #1', 'Error message #2'], + warnings: ['Warning message #1', 'Warning message #2'], + }, + }, + onChange: () => {}, + }); + + await render( + hbs`` + ); + assert + .dom(GENERAL.validationErrorByAttr('myfield')) + .exists('Validation error renders') + .hasText('Error message #1 Error message #2', 'Validation errors are combined'); + assert + .dom(GENERAL.validationWarningByAttr('myfield')) + .exists('Validation warning renders') + .hasText('Warning message #1 Warning message #2', 'Validation warnings are combined'); + }); + + // ––––– editType === 'select' / possibleValues ––––– + + test('it renders: editType=select / possibleValues - as Hds::Form::Select', async function (assert) { + const [model, spy] = await setup.call( + this, + createAttr('myfield', 'string', { editType: 'select', possibleValues: ['foo', 'bar', 'baz'] }) + ); + assert + .dom('.field [class^="hds-form-field"] select.hds-form-select') + .exists('renders as Hds::Form::Select'); + assert + .dom('select') + .hasAttribute('data-test-input', 'myfield', 'select has correct `data-test-input` attribute'); + assert.dom(GENERAL.fieldLabel()).hasText('Myfield', 'renders the select label'); + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('foo', 'has first option value'); + await fillIn(GENERAL.inputByAttr('myfield'), 'bar'); + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('bar', 'has selected option value'); + assert.strictEqual(model.get('myfield'), 'bar'); + assert.ok(spy.calledWith('myfield', 'bar'), 'onChange called with correct args'); + }); + + test('it renders: editType=select / possibleValues - with no default', async function (assert) { + const [model, spy] = await setup.call( + this, + createAttr('myfield', 'string', { + editType: 'select', + possibleValues: ['foo', 'bar', 'baz'], + noDefault: true, + }) + ); + + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('', 'has no initial value'); + await fillIn(GENERAL.inputByAttr('myfield'), 'foo'); + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('foo', 'has selected option value'); + assert.strictEqual(model.get('myfield'), 'foo'); + assert.ok(spy.calledWith('myfield', 'foo'), 'onChange called with correct args'); + }); + + test('it renders: editType=select / possibleValues - with selected value', async function (assert) { + const [model, spy] = await setup.call( + this, + createAttr('myfield', 'string', { + editType: 'select', + possibleValues: ['foo', 'bar', 'baz'], + defaultValue: 'baz', + }) + ); + + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('baz', 'has initial value selected'); + await fillIn(GENERAL.inputByAttr('myfield'), 'foo'); + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('foo', 'has selected option value'); + assert.strictEqual(model.get('myfield'), 'foo'); + assert.ok(spy.calledWith('myfield', 'foo'), 'onChange called with correct args'); + }); + + test('it renders: editType=select / possibleValues - with passed label, subtext, helptext, doclink', async function (assert) { + await setup.call( + this, + createAttr('myfield', 'string', { + editType: 'select', + possibleValues: ['foo', 'bar', 'baz'], + label: 'Custom label', + subText: 'Some subtext', + helpText: 'Some helptext', + docLink: '/docs', + }) + ); + assert.dom(GENERAL.fieldLabel()).hasText('Custom label', 'renders the custom label from options'); + assert + .dom(GENERAL.helpTextByAttr('Some subtext')) + .exists('renders `subText` option as HelperText') + .hasText( + 'Some subtext See our documentation for help.', + 'renders the right subtext string from options' + ); + assert + .dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`) + .exists('renders `docLink` option as as link inside the subtext'); + assert + .dom(GENERAL.helpTextByAttr('Some helptext')) + .exists('renders `helptext` option as HelperText') + .hasText('Some helptext', 'renders the right help text string from options'); + }); + + test('it renders: editType=select / possibleValues - with validation errors and warnings', async function (assert) { + this.setProperties({ + attr: createAttr('myfield', 'string', { editType: 'select', possibleValues: ['foo', 'bar', 'baz'] }), + model: { myfield: 'bar' }, + modelValidations: { + myfield: { + isValid: false, + errors: ['Error message #1', 'Error message #2'], + warnings: ['Warning message #1', 'Warning message #2'], + }, + }, + onChange: () => {}, + }); + + await render( + hbs`` + ); + assert + .dom(GENERAL.validationErrorByAttr('myfield')) + .exists('Validation error renders') + .hasText('Error message #1 Error message #2', 'Validation errors are combined'); + assert + .dom(GENERAL.validationWarningByAttr('myfield')) + .exists('Validation warning renders') + .hasText('Warning message #1 Warning message #2', 'Validation warnings are combined'); + }); + + // ––––– editType === 'password' ––––– + + test('it renders: editType=password / type=string - as Hds::Form::TextInput [@type=password]', async function (assert) { + const [model, spy] = await setup.call( + this, + createAttr('myfield', 'string', { editType: 'password', defaultValue: 'default' }) + ); + assert + .dom('.field [class^="hds-form-field"] input.hds-form-text-input') + .exists('renders as Hds::Form::TextInput'); + assert + .dom(`input[type="password"]`) + .exists('renders input with type=password') + .hasAttribute( + 'data-test-input', + 'myfield', + 'input[type="password"] has correct `data-test-input` attribute' + ); + assert.dom(GENERAL.fieldLabel()).hasText('Myfield', 'renders the input label'); + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('default', 'renders default value'); + await fillIn(GENERAL.inputByAttr('myfield'), 'bar'); + assert.strictEqual(model.get('myfield'), 'bar'); + assert.ok(spy.calledWith('myfield', 'bar'), 'onChange called with correct args'); + }); + + test('it renders: editType=password / type=number - as Hds::Form::TextInput [@type=password]', async function (assert) { + const [model, spy] = await setup.call( + this, + createAttr('myfield', 'number', { editType: 'password', defaultValue: 123 }) + ); + assert + .dom('.field [class^="hds-form-field"] input.hds-form-text-input') + .exists('renders as Hds::Form::TextInput'); + assert + .dom(`input${GENERAL.inputByAttr('myfield')}[type="password"]`) + .exists('renders input with type=password'); + assert.dom(GENERAL.fieldLabel()).hasText('Myfield', 'renders the input label'); + assert.dom(GENERAL.inputByAttr('myfield')).hasValue('123', 'renders default value'); + await fillIn(GENERAL.inputByAttr('myfield'), 987); + assert.strictEqual(model.get('myfield'), '987'); + assert.ok(spy.calledWith('myfield', '987'), 'onChange called with correct args'); + }); + + test('it renders: editType=password / type=string - with passed label, placeholder, subtext, helptext, doclink', async function (assert) { + await setup.call( + this, + createAttr('myfield', 'string', { + editType: 'password', + placeholder: 'Custom placeholder', + label: 'Custom label', + subText: 'Some subtext', + helpText: 'Some helptext', + docLink: '/docs', + }) + ); + assert.dom(GENERAL.fieldLabel()).hasText('Custom label', 'renders the custom label from options'); + assert + .dom(GENERAL.inputByAttr('myfield')) + .hasAttribute('placeholder', 'Custom placeholder', 'renders the placeholder from options'); + assert + .dom(GENERAL.helpTextByAttr('Some subtext')) + .exists('renders `subText` option as HelperText') + .hasText( + 'Some subtext See our documentation for help.', + 'renders the right subtext string from options' + ); + assert + .dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`) + .exists('renders `docLink` option as as link inside the subtext'); + assert + .dom(GENERAL.helpTextByAttr('Some helptext')) + .exists('renders `helptext` option as HelperText') + .hasText('Some helptext', 'renders the right help text string from options'); + }); + + test('it renders: editType=password / type=string - with validation errors and warnings', async function (assert) { + this.setProperties({ + attr: createAttr('myfield', 'string', { editType: 'password' }), + model: { myfield: 'bar' }, + modelValidations: { + myfield: { + isValid: false, + errors: ['Error message #1', 'Error message #2'], + warnings: ['Warning message #1', 'Warning message #2'], + }, + }, + onChange: () => {}, + }); + + await render( + hbs`` + ); + assert + .dom(GENERAL.validationErrorByAttr('myfield')) + .exists('Validation error renders') + .hasText('Error message #1 Error message #2', 'Validation errors are combined'); + assert + .dom(GENERAL.validationWarningByAttr('myfield')) + .exists('Validation warning renders') + .hasText('Warning message #1 Warning message #2', 'Validation warnings are combined'); }); }); diff --git a/ui/tests/integration/components/kubernetes/page/configure-test.js b/ui/tests/integration/components/kubernetes/page/configure-test.js index 5d862e1f1d..1877ccfb6a 100644 --- a/ui/tests/integration/components/kubernetes/page/configure-test.js +++ b/ui/tests/integration/components/kubernetes/page/configure-test.js @@ -12,6 +12,7 @@ import hbs from 'htmlbars-inline-precompile'; import { Response } from 'miragejs'; import sinon from 'sinon'; import { setRunOptions } from 'ember-a11y-testing/test-support'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; module('Integration | Component | kubernetes | Page::Configure', function (hooks) { setupRenderingTest(hooks); @@ -230,7 +231,7 @@ module('Integration | Component | kubernetes | Page::Configure', function (hooks await click('[data-test-config-save]'); assert - .dom('[data-test-field-validation="kubernetesHost"] [data-test-inline-error-message]') + .dom(`${GENERAL.validationErrorByAttr('kubernetesHost')} [data-test-inline-error-message]`) .hasText('Kubernetes host is required', 'Error renders for required field'); assert.dom('[data-test-alert]').hasText('There is an error with this form.', 'Alert renders'); }); diff --git a/ui/tests/integration/components/ldap/page/library/create-and-edit-test.js b/ui/tests/integration/components/ldap/page/library/create-and-edit-test.js index 5a852b953a..17958d743a 100644 --- a/ui/tests/integration/components/ldap/page/library/create-and-edit-test.js +++ b/ui/tests/integration/components/ldap/page/library/create-and-edit-test.js @@ -10,6 +10,7 @@ import { setupMirage } from 'ember-cli-mirage/test-support'; import { render, click, fillIn } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; module('Integration | Component | ldap | Page::Library::CreateAndEdit', function (hooks) { setupRenderingTest(hooks); @@ -87,10 +88,10 @@ module('Integration | Component | ldap | Page::Library::CreateAndEdit', function await click('[data-test-save]'); assert - .dom('[data-test-field-validation="name"]') + .dom(GENERAL.validationErrorByAttr('name')) .hasText('Library name is required.', 'Name validation error renders'); assert - .dom('[data-test-field-validation="service_account_names"]') + .dom(GENERAL.validationErrorByAttr('service_account_names')) .hasText('At least one service account is required.', 'Service account name validation error renders'); assert .dom('[data-test-invalid-form-message]') diff --git a/ui/tests/integration/components/pki/pki-generate-csr-test.js b/ui/tests/integration/components/pki/pki-generate-csr-test.js index 292cc38ab9..ef9a227833 100644 --- a/ui/tests/integration/components/pki/pki-generate-csr-test.js +++ b/ui/tests/integration/components/pki/pki-generate-csr-test.js @@ -92,7 +92,7 @@ module('Integration | Component | pki-generate-csr', function (hooks) { await click('[data-test-save]'); assert - .dom('[data-test-field-validation="type"]') + .dom(GENERAL.validationErrorByAttr('type')) .hasText('Type is required.', 'Type validation error renders'); assert .dom('[data-test-field="commonName"] [data-test-inline-alert]') diff --git a/ui/tests/integration/components/pki/pki-key-form-test.js b/ui/tests/integration/components/pki/pki-key-form-test.js index 54a62b171f..7820b12d36 100644 --- a/ui/tests/integration/components/pki/pki-key-form-test.js +++ b/ui/tests/integration/components/pki/pki-key-form-test.js @@ -46,10 +46,10 @@ module('Integration | Component | pki key form', function (hooks) { await click(GENERAL.saveButton); assert - .dom(GENERAL.validation('type')) + .dom(GENERAL.validationErrorByAttr('type')) .hasTextContaining('Type is required.', 'renders presence validation for type of key'); assert - .dom(GENERAL.validation('keyType')) + .dom(GENERAL.validationErrorByAttr('keyType')) .hasTextContaining('Please select a key type.', 'renders selection prompt for key type'); assert .dom(PKI_KEY_FORM.validationError) diff --git a/ui/tests/integration/components/sync/secrets/page/destinations/create-and-edit-test.js b/ui/tests/integration/components/sync/secrets/page/destinations/create-and-edit-test.js index 6a62bc9737..c1a6c55784 100644 --- a/ui/tests/integration/components/sync/secrets/page/destinations/create-and-edit-test.js +++ b/ui/tests/integration/components/sync/secrets/page/destinations/create-and-edit-test.js @@ -224,7 +224,7 @@ module('Integration | Component | sync | Secrets::Page::Destinations::CreateAndE await this.renderFormComponent(); await typeIn(PAGE.inputByAttr('teamId'), 'id'); assert - .dom(PAGE.validationWarning('teamId')) + .dom(PAGE.validationWarningByAttr('teamId')) .doesNotExist('does not render warning validation for new vercel-project destination'); // existing model @@ -240,7 +240,7 @@ module('Integration | Component | sync | Secrets::Page::Destinations::CreateAndE await PAGE.form.fillInByAttr('teamId', ''); await typeIn(PAGE.inputByAttr('teamId'), 'edit'); assert - .dom(PAGE.validationWarning('teamId')) + .dom(PAGE.validationWarningByAttr('teamId')) .hasText( 'Team ID should only be updated if the project was transferred to another account.', 'it renders validation warning' @@ -338,7 +338,7 @@ module('Integration | Component | sync | Secrets::Page::Destinations::CreateAndE // only asserts validations for presence, refactor if validations change for (const attr in validationAssertions) { const { message } = validationAssertions[attr].find((v) => v.type === 'presence'); - assert.dom(PAGE.validation(attr)).hasText(message, `renders validation: ${message}`); + assert.dom(PAGE.validationErrorByAttr(attr)).hasText(message, `renders validation: ${message}`); } }); }); diff --git a/ui/tests/integration/components/text-file-test.js b/ui/tests/integration/components/text-file-test.js index d46d65b031..5f924eb9d2 100644 --- a/ui/tests/integration/components/text-file-test.js +++ b/ui/tests/integration/components/text-file-test.js @@ -10,6 +10,7 @@ import { hbs } from 'ember-cli-htmlbars'; import sinon from 'sinon'; import { setRunOptions } from 'ember-a11y-testing/test-support'; import { CERTIFICATES } from 'vault/tests/helpers/pki/pki-helpers'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; const SELECTORS = { label: '[data-test-text-file-label]', @@ -97,9 +98,7 @@ module('Integration | Component | text-file', function (hooks) { await render(hbs``); await triggerEvent(SELECTORS.fileUpload, 'change', { files: [this.file] }); - assert - .dom('[data-test-field-validation="text-file"]') - .hasText('There was a problem uploading. Please try again.'); + assert.dom(GENERAL.inlineAlert).hasText('There was a problem uploading. Please try again.'); assert.propEqual( this.onChange.lastCall.args[0], {