refactor: 💡 remove rose::notification in favor of hds (#2557)

* refactor: 💡 remove rose::notification in favor of hds

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-15634
This commit is contained in:
Lisbet Alvarez authored and GitHub committed 2024-11-19 15:18:18 -08:00
1 parent 66e9e971a1
commit 543cf4697f
84 files changed
+398 -591

No files matched your search

@@ -8,7 +8,6 @@ delete: Delete
remove: Remove
discard: Discard
disconnect: Disconnect
dismiss: Dismiss
save: Save
submit: Submit
manage: Manage
@@ -1,41 +0,0 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
<section
...attributes
class='rose-notification is-{{@style}}{{if @dismiss " is-dismissible"}}'
role='alert'
aria-live={{if @dismiss 'assertive'}}
aria-atomic='true'
>
<header class='rose-notification-header'>
<Rose::Icon
class='rose-notification-icon'
@name={{this.icon}}
@size='medium'
/>
{{@heading}}
</header>
<div class='rose-notification-body'>
{{yield}}
</div>
{{#if @dismiss}}
<button
type='button'
class='rose-notification-dismiss'
title={{@dismissText}}
{{on 'click' @dismiss}}
>
<Rose::Icon @name='flight-icons/svg/x-16' @size='medium' />
<span class='rose-notification-dismiss-text'>
{{@dismissText}}
</span>
</button>
{{/if}}
</section>
@@ -1,32 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { computed } from '@ember/object';
export default class RoseNotificationComponent extends Component {
/**
* Returns an icon name based on the notification style.
* @type {string}
*/
@computed('style')
get icon() {
let icon = 'flight-icons/svg/info-16';
switch (this.style) {
case 'error':
icon = 'flight-icons/svg/x-square-16';
break;
case 'success':
icon = 'flight-icons/svg/check-circle-16';
break;
case 'warning':
icon = 'flight-icons/svg/alert-triangle-16';
break;
}
return icon;
}
}
@@ -0,0 +1,18 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
export default function mapTypeToColor(flashMsgType) {
// Maps the flash message type parameter to the correct hds color.
switch (flashMsgType) {
case 'error':
return 'critical';
case 'success':
return 'success';
case 'warning':
return 'warning';
default:
return 'neutral';
}
}
@@ -0,0 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
export { default } from 'rose/helpers/map-type-to-color';
@@ -12,7 +12,6 @@
@import 'layout';
@import 'icon';
@import 'list';
@import 'notification';
@import 'card';
@import 'cards';
@import 'page-header';
@@ -1,106 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@use '../variables/sizing';
@use '../utilities/type';
.rose-notification {
$s: sizing.rems(s); // 12
$xs: sizing.rems(xs); // 8
$xxs: sizing.rems(xxs); // 4
$xxxs: sizing.rems(xxxs); // 2
$xxxxs: sizing.rems(xxxxs); // 1
position: relative;
padding: sizing.rems(m);
margin-bottom: sizing.rems(m);
border: sizing.rems(xxxxs) solid;
border-radius: $xxxs;
box-shadow:
0 $xs $s rgba(var(--stark-components), var(--opacity-3)),
0 $xxs $xxs rgba(var(--stark-components), var(--opacity-4));
.rose-notification-icon {
position: relative;
top: $xxxxs;
color: var(--icon-color);
}
.rose-notification-header {
color: var(--header-color);
@include type.type(m, semibold);
}
.rose-notification-body {
@include type.type(s);
// hack alert, because the icons are still hard to work with
margin-left: sizing.rems(m) + $xxs;
overflow-wrap: break-word;
}
.rose-notification-dismiss {
position: absolute;
color: currentcolor;
background-color: transparent;
border-radius: $xxxs;
border: 0;
padding: 0;
cursor: pointer;
top: sizing.rems(s);
right: sizing.rems(s);
.rose-icon {
display: block;
padding: $xxs;
}
.rose-notification-dismiss-text {
position: absolute;
top: -1000px;
left: -1000px;
width: 1px;
height: 1px;
opacity: 0;
}
&:hover {
background-color: rgba(var(--stark-components), var(--opacity-3));
}
&:active {
background-color: rgba(var(--stark-components), var(--opacity-2));
}
}
--icon-color: var(--info);
--header-color: var(--info-starker-1);
--border-color: var(--info-subtler-1);
--background-color: var(--info-subtler-3);
border-color: var(--border-color);
background-color: var(--background-color);
&.is-error {
--icon-color: var(--failure);
--header-color: var(--failure);
--border-color: var(--failure-subtler-1);
--background-color: var(--failure-subtler-2);
}
&.is-success {
--icon-color: var(--success);
--header-color: var(--success-starker-1);
--border-color: var(--success-subtler-1);
--background-color: var(--success-subtler-2);
}
&.is-warning {
--icon-color: var(--warning);
--header-color: var(--warning-starker-1);
--border-color: var(--warning-subtler-1);
--background-color: var(--warning-subtler-2);
}
}
@@ -1,41 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find, click } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | rose/notification', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`
<Rose::Notification
@style="info"
@heading="Alert Notification"
>
An error occurred.
</Rose::Notification>
`);
assert.ok(find('.rose-notification'));
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'An error occurred.',
);
});
test('it has optional dismiss button which triggers a function', async function (assert) {
assert.expect(1);
this.dismiss = () => assert.ok(true, 'dismiss clicked');
await render(hbs`
<Rose::Notification
@style="info"
@heading="Alert Notification"
@dismiss={{this.dismiss}} />
`);
await click('.rose-notification-dismiss');
});
});
@@ -0,0 +1,45 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Helper | map-type-to-color', function (hooks) {
setupRenderingTest(hooks);
test('it returns correct color when flash message type is `success`', async function (assert) {
this.set('inputValue', 'success');
await render(hbs`{{map-type-to-color this.inputValue}}`);
assert.dom(this.element).hasText('success');
});
test('it returns correct color when flash message type is `error`', async function (assert) {
this.set('inputValue', 'error');
await render(hbs`{{map-type-to-color this.inputValue}}`);
assert.dom(this.element).hasText('critical');
});
test('it returns correct color when flash message type is `warning`', async function (assert) {
this.set('inputValue', 'warning');
await render(hbs`{{map-type-to-color this.inputValue}}`);
assert.dom(this.element).hasText('warning');
});
test('it returns default color when flash message type does not match', async function (assert) {
this.set('inputValue', 'other');
await render(hbs`{{map-type-to-color this.inputValue}}`);
assert.dom(this.element).hasText('neutral');
});
});
+12 -24
View File
@@ -6,60 +6,55 @@
// This file is essentially a rip of the default ember notify styles with some minor tweaks for positioning.
@-webkit-keyframes ember-notify-show {
from {
left: -310px;
right: -310px;
}
to {
left: 0;
right: 0;
}
}
@keyframes ember-notify-show {
from {
left: -310px;
right: -310px;
}
to {
left: 0;
right: 0;
}
}
@-webkit-keyframes ember-notify-hide {
from {
left: 0;
right: 0;
}
to {
left: -310px;
right: -310px;
}
}
@keyframes ember-notify-hide {
from {
left: 0;
right: 0;
}
to {
left: -310px;
right: -310px;
}
}
.ember-notify-cn {
bottom: 0;
left: 0;
max-width: 300px;
right: 0;
position: fixed;
z-index: 5000;
margin-bottom: 16px;
}
.ember-notify {
box-sizing: border-box;
display: block;
margin: 10px;
margin: 16px 24px;
position: relative;
width: 300px;
.close {
cursor: pointer;
float: right;
}
width: 360px;
}
.ember-notify-show {
@@ -87,14 +82,7 @@
}
@media only screen and (width <= 680px) {
.ember-notify-cn {
box-sizing: border-box;
padding-left: 20px;
width: 100%;
}
.ember-notify {
float: right;
width: 100%;
}
}
+10 -13
View File
@@ -114,21 +114,18 @@
</Rose::Layout::Global>
{{#if this.flashMessages.queue}}
<div class='ember-notify-cn ember-notify-default'>
<div class='ember-notify-cn'>
{{#each this.flashMessages.queue as |flash|}}
<div
class='ember-notify-show callout
{{flash.notificationType}}
ember-view ember-notify clearfix'
>
<Rose::Notification
@style={{flash.notificationType}}
@heading={{t (concat 'states.' flash.notificationType)}}
@dismiss={{fn flash.dismiss flash}}
@dismissText={{t 'actions.dismiss'}}
<div class='ember-notify-show ember-notify'>
<Hds::Toast
@color={{map-type-to-color flash.notificationType}}
@onDismiss={{fn flash.dismiss flash}}
data-test-toast-notification
as |T|
>
{{flash.message}}
</Rose::Notification>
<T.Title>{{t (concat 'states.' flash.notificationType)}}</T.Title>
<T.Description>{{flash.message}}</T.Description>
</Hds::Toast>
</div>
{{/each}}
</div>
@@ -7,11 +7,9 @@
<main>
<Rose::Layout::Centered>
<Rose::Notification
@style='success'
@heading={{t 'auth.titles.flow-success'}}
>
{{t 'auth.descriptions.flow-success'}}
</Rose::Notification>
<Hds::Alert @type='page' @color='success' as |A|>
<A.Title>{{t 'auth.titles.flow-success'}}</A.Title>
<A.Description>{{t 'auth.descriptions.flow-success'}}</A.Description>
</Hds::Alert>
</Rose::Layout::Centered>
</main>
@@ -7,10 +7,12 @@
<main>
<Rose::Layout::Centered>
<Rose::Notification @style='error' @heading={{t 'auth.titles.flow-error'}}>
{{t 'auth.descriptions.flow-error'}}
<br />
<Hds::Copy::Snippet @textToCopy={{@model}} @color='secondary' />
</Rose::Notification>
<Hds::Alert @type='page' @color='critical' as |A|>
<A.Title>{{t 'auth.titles.flow-error'}}</A.Title>
<A.Description>
{{t 'auth.descriptions.flow-error'}}
<Hds::Copy::Snippet @textToCopy={{@model}} @color='secondary' />
</A.Description>
</Hds::Alert>
</Rose::Layout::Centered>
</main>
@@ -26,7 +26,8 @@ module('Acceptance | aliases | create', function (hooks) {
const DESTINATION_ID_SELECTOR = '[name="destination_id"]';
const HOST_ID_SELECTOR = '[name="authorize_session_arguments"]';
const ALERT_TEXT_SELECTOR = '[role="alert"] div';
const ALERT_TEXT_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const NAME_FIELD_TEXT = 'random string';
@@ -32,7 +32,8 @@ module('Acceptance | auth-methods | create', function (hooks) {
const NAME_INPUT_SELECTOR = '[name="name"]';
const URLS_INPUT_SELECTOR = '[name="urls"]';
const DESC_INPUT_SELECTOR = '[name="description"]';
const ERROR_MSG_SELECTOR = '.rose-notification-body';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const CERTIFICATES_BTN_SELECTOR = '[name="certificates"] button';
@@ -28,7 +28,8 @@ module('Acceptance | auth-methods | delete', function (hooks) {
const DIALOG_DELETE_BTN_SELECTOR = '.rose-dialog .rose-button-primary';
const DIALOG_CANCEL_BTN_SELECTOR = '.rose-dialog .rose-button-secondary';
const ERROR_MSG_SELECTOR = '.rose-notification-body';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const MANAGE_DROPDOWN_SELECTOR =
'[data-test-manage-auth-method] button:first-child';
@@ -151,10 +151,8 @@ module('Acceptance | auth-methods | oidc', function (hooks) {
authMethod.attributes.state,
'Auth method state is not be updated.',
);
assert.ok(
find('.rose-notification-body').textContent.trim(),
'Sorry!',
'Displays error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Sorry!');
});
});
@@ -33,7 +33,8 @@ module('Acceptance | auth-methods | update', function (hooks) {
const NAME_INPUT_SELECTOR = '[name="name"]';
const URLS_INPUT_SELECTOR = '[name="urls"]';
const DESC_INPUT_SELECTOR = '[name="description"]';
const ERROR_MSG_SELECTOR = '.rose-notification-body';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const CERTIFICATES_REMOVE_BTN_SELECTOR =
'[name="certificates"] [data-test-remove-button]';
@@ -9,7 +9,6 @@ import {
currentURL,
fillIn,
click,
find,
findAll,
getRootElement,
} from '@ember/test-helpers';
@@ -268,7 +267,9 @@ module('Acceptance | authentication', function (hooks) {
assert.notOk(currentSession().isAuthenticated);
await fillIn('[name="identification"]', 'error');
await click('[type="submit"]');
assert.ok(find('.rose-notification.is-error'));
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
assert.notOk(currentSession().isAuthenticated);
});
@@ -134,6 +134,8 @@ module('Acceptance | credential-libraries | delete', function (hooks) {
await visit(urls.credentialLibrary);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -160,10 +160,9 @@ module('Acceptance | credential-libraries | update', function (hooks) {
await click(BUTTON_SELECTOR, 'Activate edit mode');
await fillIn(NAME_INPUT_SELECTOR, 'random string');
await click(SAVE_BTN_SELECTOR);
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find(FIELD_ERROR_TEXT_SELECTOR).textContent.trim(),
'Name is required.',
@@ -131,10 +131,9 @@ module('Acceptance | credential-stores | create', function (hooks) {
});
await visit(urls.newCredentialStore);
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -234,7 +234,7 @@ module(
await click('[type="submit"]');
assert
.dom('.rose-notification-body')
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Error in provided request.');
assert
.dom('[data-test-error-message-password]')
@@ -269,7 +269,7 @@ module(
await click('[type="submit"]');
assert
.dom('.rose-notification-body')
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Error in provided request.');
assert
.dom('[data-test-error-message-private-key]')
@@ -304,7 +304,7 @@ module(
await click('[type="submit"]');
assert
.dom('.rose-notification-body')
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Error in provided request.');
});
@@ -7,7 +7,7 @@ import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { authenticateSession } from 'ember-simple-auth/test-support';
import { click, currentURL, visit, find } from '@ember/test-helpers';
import { click, currentURL, visit } from '@ember/test-helpers';
import { Response } from 'miragejs';
module(
@@ -277,7 +277,9 @@ module(
await visit(urls.usernamePasswordCredential);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
test('deleting a username & key pair credential which errors displays error message', async function (assert) {
@@ -295,7 +297,9 @@ module(
await visit(urls.usernameKeyPairCredential);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
test('deleting a JSON credential which errors displays error message', async function (assert) {
@@ -313,7 +317,9 @@ module(
await visit(urls.jsonCredential);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
},
);
@@ -232,10 +232,9 @@ module(
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', mockInput);
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Error in provided request.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Error in provided request.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -267,10 +266,9 @@ module(
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', mockInput);
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Error in provided request.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Error in provided request.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -302,10 +300,9 @@ module(
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', mockInput);
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Error in provided request.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Error in provided request.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -4,7 +4,7 @@
*/
import { module, test } from 'qunit';
import { visit, find, click } from '@ember/test-helpers';
import { visit, click } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
@@ -181,7 +181,9 @@ module('Acceptance | credential-stores | delete', function (hooks) {
await visit(urls.staticCredentialStore);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
test('deleting a vault credential store which errors displays error messages', async function (assert) {
@@ -199,6 +201,8 @@ module('Acceptance | credential-stores | delete', function (hooks) {
await visit(urls.vaultCredentialStore);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -156,10 +156,9 @@ module('Acceptance | credential-stores | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -190,10 +189,9 @@ module('Acceptance | credential-stores | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -85,10 +85,8 @@ module('Acceptance | groups | delete', function (hooks) {
await visit(urls.group);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -104,7 +104,9 @@ module('Acceptance | groups | members', function (hooks) {
assert.strictEqual(findAll('tbody tr').length, membersCount);
await click('.hds-dropdown-toggle-icon');
await click('tbody tr .hds-dropdown-list-item button');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('visiting member selection', async function (assert) {
@@ -176,6 +178,8 @@ module('Acceptance | groups | members', function (hooks) {
await visit(urls.addMembers);
await click('tbody label');
await click('form [type="submit"]');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
});
@@ -96,11 +96,9 @@ module('Acceptance | groups | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.strictEqual(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -29,7 +29,8 @@ module('Acceptance | host-catalogs | create', function (hooks) {
const TYPE_INPUT_SELECTOR = '[name="type"]';
const SAVE_BUTTON_SELECTOR = '[type="submit"]';
const CANCEL_BUTTON_SELECTOR = '.rose-form-actions [type="button"]';
const ALERT_TEXT_SELECTOR = '[role="alert"]';
const ALERT_TEXT_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const instances = {
scopes: {
@@ -104,7 +104,9 @@ module('Acceptance | host-catalogs | delete', function (hooks) {
await click(DELETE_ACTION_SELECTOR);
await click('.rose-dialog .rose-button-primary');
assert.dom('.rose-notification-body').hasText('Deleted successfully.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Deleted successfully.');
assert.strictEqual(getHostCatalogCount(), hostCatalogCount - 1);
assert.strictEqual(currentURL(), urls.hostCatalogs);
});
@@ -142,6 +144,8 @@ module('Acceptance | host-catalogs | delete', function (hooks) {
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.dom('.rose-notification-body').hasText('Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -208,10 +208,9 @@ module('Acceptance | host-catalogs | host sets | create', function (hooks) {
});
await visit(urls.newHostSet);
await click(SUBMIT_BTN_SELECTOR);
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -138,6 +138,8 @@ module('Acceptance | host-catalogs | host sets | delete', function (hooks) {
await visit(urls.hostSet);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -136,7 +136,9 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) {
assert.strictEqual(findAll('tbody tr').length, getHostSetHostCount());
await click('[data-test-host-set-hosts-dropdown-toggle]');
await click('[data-test-host-set-hosts-dropdown-remove-host]');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('visiting add hosts', async function (assert) {
@@ -209,7 +211,9 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) {
await visit(urls.addHosts);
await click('tbody .hds-table__tr .hds-form-label');
await click('form [type="submit"]');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('visiting host creation from a host set', async function (assert) {
@@ -255,7 +259,9 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) {
await visit(urls.createAndAddHost);
await fillIn('[name="name"]', 'New Host');
await click('form [type="submit"]');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('shows error message on host addition to host set error', async function (assert) {
@@ -275,7 +281,9 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) {
await visit(urls.createAndAddHost);
await fillIn('[name="name"]', 'New Host');
await click('form [type="submit"]');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('users can navigate to host and incorrect url autocorrects', async function (assert) {
@@ -149,10 +149,9 @@ module('Acceptance | host-catalogs | host sets | update', function (hooks) {
});
await visit(urls.newHostSet);
await click(SUBMIT_BTN_SELECTOR);
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -292,10 +291,9 @@ module('Acceptance | host-catalogs | host sets | update', function (hooks) {
await click(EDIT_BUTTON_SELECTOR, 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click(SUBMIT_BTN_SELECTOR);
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -137,6 +137,8 @@ module('Acceptance | host-catalogs | hosts | delete', function (hooks) {
await visit(urls.host);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -125,10 +125,9 @@ module('Acceptance | host-catalogs | hosts | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.ok(
find('[role="alert"]').textContent.trim(),
'The request was invalid.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required.',
@@ -167,7 +167,9 @@ module('Acceptance | host-catalogs | update', function (hooks) {
await fillIn(NAME_INPUT_SELECTOR, 'random string');
await click('[type="submit"]');
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('[data-test-error-message-name]').hasText('Name is required.');
});
@@ -28,7 +28,8 @@ module('Acceptance | managed-groups | create', function (hooks) {
const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]';
const NAME_INPUT_SELECTOR = '[name="name"]';
const DESC_INPUT_SELECTOR = '[name="description"]';
const ERROR_MSG_SELECTOR = '.rose-notification-body';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const MANAGE_DROPDOWN_SELECTOR =
'[data-test-manage-auth-method] button:first-child';
@@ -25,7 +25,8 @@ module('Acceptance | managed-groups | delete', function (hooks) {
'[data-test-managed-group-dropdown] button:first-child';
const DELETE_ACTION_SELECTOR =
'[data-test-managed-group-dropdown] ul li button';
const ERROR_MSG_SELECTOR = '.rose-notification-body';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const instances = {
scopes: {
@@ -22,7 +22,8 @@ module('Acceptance | policies | create', function (hooks) {
const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]';
const NAME_FIELD_SELECTOR = '[name="name"]';
const RETAIN_FOR_TEXT_INPUT = '[data-input="retain_for"]';
const ALERT_TEXT_SELECTOR = '[role="alert"] div';
const ALERT_TEXT_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const NAME_FIELD_TEXT = 'random string';
const DELETE_AFTER_TEXT_INPUT = '[data-input="delete_after"]';
@@ -130,7 +130,9 @@ module('Acceptance | roles | create', function (hooks) {
await fillIn('[name="name"]', 'new target');
await click('form [type="submit"]');
await a11yAudit();
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.ok(find('.hds-form-error__message'));
});
@@ -96,10 +96,8 @@ module('Acceptance | roles | delete', function (hooks) {
await visit(urls.role);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_DROPDOWN_SELECTOR);
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'Oops.',
'Displays primary error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -48,7 +48,8 @@ module('Acceptance | roles | global-scope', function (hooks) {
const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]';
const MANAGE_DROPDOWN_SELECTOR = '.hds-dropdown-toggle-button';
const MANAGE_SCOPES_SELECTOR = '[data-test-manage-dropdown-scopes]';
const TOAST_SELECTOR = '[role="alert"]';
const TOAST_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const SEARCH_INPUT_SELECTOR = '.search-filtering [type="search"]';
const NO_RESULTS_MSG_SELECTOR = '[data-test-no-grant-scope-results]';
const NO_SCOPES_MSG_SELECTOR = '.role-grant-scopes div';
@@ -139,7 +139,9 @@ module('Acceptance | roles | grants', function (hooks) {
);
await fillIn(`${grantsForm} [name="grant"]`, 'ids=123,action=delete');
await click('.rose-form-actions [type="submit"]:not(:disabled)');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('create a grant', async function (assert) {
@@ -192,7 +194,7 @@ module('Acceptance | roles | grants', function (hooks) {
await fillIn(`${newGrantForm} [name="grant"]`, 'ids=123,action=delete');
await click(`${newGrantForm} [type="submit"]:not(:disabled)`);
await click('.rose-form-actions [type="submit"]:not(:disabled)');
assert.ok(find('[role="alert"]'));
assert.ok(find('[data-test-toast-notification] .hds-alert__description'));
});
test('delete a grant', async function (assert) {
@@ -235,6 +237,6 @@ module('Acceptance | roles | grants', function (hooks) {
);
await click(`${grantsForm} button:not([type="submit"])`);
await click('.rose-form-actions [type="submit"]:not(:disabled)');
assert.ok(find('[role="alert"]'));
assert.ok(find('[data-test-toast-notification] .hds-alert__description'));
});
});
@@ -45,7 +45,8 @@ module('Acceptance | roles | org-scope', function (hooks) {
const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]';
const MANAGE_DROPDOWN_SELECTOR = '.hds-dropdown-toggle-button';
const MANAGE_SCOPES_SELECTOR = '[data-test-manage-dropdown-scopes]';
const TOAST_SELECTOR = '[role="alert"]';
const TOAST_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const SEARCH_INPUT_SELECTOR = '.search-filtering [type="search"]';
const NO_RESULTS_MSG_SELECTOR = '[data-test-no-grant-scope-results]';
const NO_SCOPES_MSG_SELECTOR = '.role-grant-scopes div';
@@ -105,7 +105,9 @@ module('Acceptance | roles | principals', function (hooks) {
assert.strictEqual(findAll('tbody tr').length, principalsCount);
await click('.hds-dropdown-toggle-icon');
await click('tbody tr .hds-dropdown-list-item button');
assert.ok(find('[role="alert"]'));
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('cannot navigate to add principals without proper authorization', async function (assert) {
@@ -166,6 +168,6 @@ module('Acceptance | roles | principals', function (hooks) {
await visit(urls.addPrincipals);
await click('tbody label');
await click('form [type="submit"]');
assert.ok(find('[role="alert"]'));
assert.ok(find('[data-test-toast-notification] .hds-alert__description'));
});
});
@@ -108,11 +108,9 @@ module('Acceptance | roles | update', function (hooks) {
await click('form [type="button"]', 'Activate edit mode');
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.strictEqual(
find('.hds-form-error__message').textContent.trim(),
'Name is required.',
+3 -1
View File
@@ -217,7 +217,9 @@ module('Acceptance | scopes', function (hooks) {
await click(`[href="${urls.newOrgScope}"]`);
await click(SAVE_BUTTON_SELECTOR);
assert.dom('.rose-notification-body').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('.hds-form-error__message').hasText('Name is required.');
});
});
@@ -136,6 +136,8 @@ module('Acceptance | scopes | delete', function (hooks) {
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.dom('.rose-notification-body').hasText('Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -127,7 +127,9 @@ module('Acceptance | scopes | update', function (hooks) {
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('.hds-form-error__message').hasText('Name is required.');
});
@@ -23,7 +23,8 @@ module(
const DELETE_DROPDOWN_SELECTOR = '[data-test-manage-dropdown-delete]';
const DROPDOWN_SELECTOR = '[data-test-manage-dropdown]';
const ERROR_MSG_SELECTOR = '.rose-notification-body';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
// Instances
const instances = {
@@ -141,9 +142,7 @@ module(
// if there was an error player will not render
assert.dom('.session-recording-player').doesNotExist();
assert.dom('.hds-application-state__title').hasText('Playback error');
assert
.dom('.rose-notification-body')
.includesText('rpc error: code = Unknown');
assert.dom(ERROR_MSG_SELECTOR).includesText('rpc error: code = Unknown');
});
test('user can navigate back to session recording screen', async function (assert) {
@@ -169,7 +169,9 @@ module('Acceptance | sessions | list', function (hooks) {
await click(`[href="${urls.sessions}"]`);
await click('tbody tr:first-child td:last-child button');
assert.dom('[role="alert"] .rose-notification-header').hasText('Success');
assert
.dom('[data-test-toast-notification] .hds-alert__title')
.hasText('Success');
});
test('cancelling a session with error shows notification', async function (assert) {
@@ -179,7 +181,9 @@ module('Acceptance | sessions | list', function (hooks) {
await click(`[href="${urls.sessions}"]`);
await click('tbody tr:first-child td:last-child button');
assert.dom('[role="alert"] .rose-notification-header').hasText('Error');
assert
.dom('[data-test-toast-notification] .hds-alert__title')
.hasText('Error');
});
test('users can link to docs page for sessions', async function (assert) {
@@ -91,7 +91,9 @@ module('Acceptance | storage-buckets | create', function (hooks) {
name: commonSelectors.FIELD_NAME_VALUE,
});
assert.dom(selectors.TOAST).hasText(selectors.TOAST_SUCCESSFULL_VALUE);
assert
.dom(commonSelectors.ALERT_TOAST_BODY)
.hasText(selectors.TOAST_SUCCESSFUL_VALUE);
assert.strictEqual(storageBucket.name, commonSelectors.FIELD_NAME_VALUE);
assert.strictEqual(storageBucket.scopeId, instances.scopes.org.id);
assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1);
@@ -124,7 +126,9 @@ module('Acceptance | storage-buckets | create', function (hooks) {
const storageBucket = this.server.schema.storageBuckets.findBy({
name: commonSelectors.FIELD_NAME_VALUE,
});
assert.dom(selectors.TOAST).hasText(selectors.TOAST_SUCCESSFULL_VALUE);
assert
.dom(commonSelectors.ALERT_TOAST_BODY)
.hasText(selectors.TOAST_SUCCESSFUL_VALUE);
assert.strictEqual(storageBucket.name, commonSelectors.FIELD_NAME_VALUE);
assert.strictEqual(
storageBucket.attributes.endpoint_url,
@@ -267,7 +271,9 @@ module('Acceptance | storage-buckets | create', function (hooks) {
await click(commonSelectors.SAVE_BTN);
await a11yAudit();
assert.dom(selectors.TOAST).hasText('The request was invalid.');
assert
.dom(commonSelectors.ALERT_TOAST_BODY)
.hasText('The request was invalid.');
assert
.dom(selectors.FIELD_BUCKET_NAME_ERROR)
.hasText('This is a required field.');
@@ -25,7 +25,8 @@ module('Acceptance | storage-buckets | delete', function (hooks) {
const DIALOG_CANCEL_BTN_SELECTOR = '.rose-dialog .rose-button-secondary';
const DIALOG_MESSAGE_SELECTOR = '.rose-dialog-body';
const DIALOG_TITLE_SELECTOR = '.rose-dialog-header';
const NOTIFICATION_MSG_SELECTOR = '.rose-notification-body';
const NOTIFICATION_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const NOTIFICATION_MSG_TEXT = 'Deleted successfully.';
const instances = {
@@ -29,8 +29,7 @@ export const FIELD_SECRET_KEY_EDIT_BTN =
'[data-test-secret-access-key] [type=button]';
export const FIELD_WORKER_FILTER = '[name=worker_filter]';
export const FIELD_WORKER_FILTER_ERROR = '[data-test-worker-filter-error]';
export const TOAST = '[role=alert] div';
export const TOAST_SUCCESSFULL_VALUE = 'Saved successfully.';
export const TOAST_SUCCESSFUL_VALUE = 'Saved successfully.';
export const TABLE_FIRST_ROW_ACTION_DROPDOWN =
'tbody tr:first-child td:last-child button';
@@ -170,7 +170,9 @@ module('Acceptance | storage-buckets | update', function (hooks) {
await fillIn(selectors.FIELD_WORKER_FILTER, 'random string');
await click(commonSelectors.SAVE_BTN);
assert.dom(selectors.TOAST).hasText('The request was invalid.');
assert
.dom(commonSelectors.ALERT_TOAST_BODY)
.hasText('The request was invalid.');
assert
.dom(selectors.FIELD_BUCKET_NAME_ERROR)
.hasText('This is a required field.');
@@ -298,7 +298,9 @@ module('Acceptance | targets | brokered credential sources', function (hooks) {
await click('tbody tr:last-child label');
await click('tbody tr:first-child label');
await click('form [type="submit"]');
assert.dom('[role="alert"]').isVisible();
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.isVisible();
});
test('can remove a vault type credential library', async function (assert) {
@@ -367,7 +369,9 @@ module('Acceptance | targets | brokered credential sources', function (hooks) {
assert.strictEqual(findAll('tbody tr').length, count);
await click('.hds-dropdown-toggle-icon');
await click('tbody tr .hds-dropdown-list-item button');
assert.dom('[role="alert"]').isVisible();
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.isVisible();
});
test('removing a target credential which errors displays error messages', async function (assert) {
@@ -391,6 +395,8 @@ module('Acceptance | targets | brokered credential sources', function (hooks) {
assert.strictEqual(findAll('tbody tr').length, count);
await click('.hds-dropdown-toggle-icon');
await click('tbody tr .hds-dropdown-list-item button');
assert.dom('[role="alert"]').isVisible();
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.isVisible();
});
});
@@ -27,7 +27,8 @@ module('Acceptance | targets | create-alias', function (hooks) {
const NAME_FIELD_SELECTOR = '[name="name"]';
const ALIAS_FIELD_SELECTOR = '[name="value"]';
const DEST_FIELD_SELECTOR = '[name="destination_id"]';
const ALERT_TEXT_SELECTOR = '[role="alert"] div';
const ALERT_TEXT_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const NAME_FIELD_TEXT = 'random string';
const ALIAS_VALUE_TEXT = 'www.target1.com';
@@ -281,7 +281,9 @@ module('Acceptance | targets | create', function (hooks) {
await visit(urls.newTCPTarget);
await click(SAVE_BTN_SELECTOR);
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('.hds-form-error__message').hasText('Name is required.');
});
@@ -308,7 +310,9 @@ module('Acceptance | targets | create', function (hooks) {
await visit(urls.newSSHTarget);
await click(SAVE_BTN_SELECTOR);
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('.hds-form-error__message').hasText('Name is required.');
});
@@ -89,7 +89,9 @@ module('Acceptance | targets | delete', function (hooks) {
await click(DELETE_ACTION_SELECTOR);
await click('.rose-dialog .rose-button-primary');
assert.dom('.rose-notification-body').hasText('Deleted successfully.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Deleted successfully.');
assert.strictEqual(getTargetCount(), targetCount - 1);
assert.strictEqual(currentURL(), urls.targets);
});
@@ -139,6 +141,8 @@ module('Acceptance | targets | delete', function (hooks) {
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.dom('.rose-notification-body').hasText('Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -24,7 +24,8 @@ module(
const SAVE_BTN_SELECTOR = '[type="submit"]';
const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]';
const NAME_FIELD_SELECTOR = '[name="name"]';
const ALERT_TEXT_SELECTOR = '[role="alert"] div';
const ALERT_TEXT_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const NAME_FIELD_TEXT = 'random string';
const BUCKET_NAME_FIELD_SELECTOR = '[name="bucket_name"]';
@@ -167,7 +167,9 @@ module('Acceptance | targets | host-sources', function (hooks) {
await click('tbody tr .hds-dropdown-list-item button');
assert.dom('tbody tr').exists({ count: targetHostSetCount });
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('select and save host sets to add', async function (assert) {
@@ -251,7 +253,9 @@ module('Acceptance | targets | host-sources', function (hooks) {
assert.strictEqual(currentURL(), urls.targetAddHostSources);
assert.strictEqual(getTargetHostSetCount(), targetHostSetCount);
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
});
test('saving host source with address brings up confirmation modal and removes address', async function (assert) {
@@ -319,7 +319,9 @@ module(
await click('tbody tr:last-child label');
await click('tbody tr:first-child label');
await click('form [type="submit"]');
assert.dom('[role="alert"]').isVisible();
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.isVisible();
});
test('can remove a vault type credential library', async function (assert) {
@@ -392,7 +394,9 @@ module(
assert.strictEqual(findAll('tbody tr').length, count);
await click('.hds-dropdown-toggle-icon');
await click('tbody tr .hds-dropdown-list-item button');
assert.dom('[role="alert"]').isVisible();
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.isVisible();
});
test('removing a target credential which errors displays error messages', async function (assert) {
@@ -418,7 +422,9 @@ module(
assert.strictEqual(findAll('tbody tr').length, count);
await click('.hds-dropdown-toggle-icon');
await click('tbody tr .hds-dropdown-list-item button');
assert.dom('[role="alert"]').isVisible();
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.isVisible();
});
},
);
@@ -120,7 +120,9 @@ module('Acceptance | targets | update', function (hooks) {
await fillIn('[name="name"]', 'random string');
await click('[type="submit"]');
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('.hds-form-error__message').hasText('Name is required.');
});
@@ -29,7 +29,8 @@ module('Acceptance | users | accounts', function (hooks) {
'[data-test-manage-user-dropdown] ul li:first-child a';
const MANAGE_DROPDOWN_SELECTOR =
'[data-test-manage-user-dropdown] button:first-child';
const ERROR_MSG_SELECTOR = '[role="alert"]';
const ERROR_MSG_SELECTOR =
'[data-test-toast-notification] .hds-alert__description';
const TABLE_ROWS_SELECTOR = 'tbody tr';
const CHECKBOX_SELECTOR = 'tbody label';
const SUBMIT_BTN_SELECTOR = 'form [type="submit"]';
@@ -139,7 +139,9 @@ module('Acceptance | users | create', function (hooks) {
await click('[type="submit"]');
assert.strictEqual(getUsersCount(), usersCount);
assert.dom('.rose-notification-body').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('[data-test-error-message-name]').hasText('Name is required.');
});
@@ -88,7 +88,9 @@ module('Acceptance | users | delete', function (hooks) {
await click(DELETE_ACTION_SELECTOR);
await click('.rose-dialog .rose-button-primary');
assert.dom('.rose-notification-body').hasText('Deleted successfully.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Deleted successfully.');
assert.strictEqual(this.server.db.users.length, usersCount - 1);
assert.strictEqual(currentURL(), urls.users);
});
@@ -125,6 +127,8 @@ module('Acceptance | users | delete', function (hooks) {
await click(`[href="${urls.user}"]`);
await click(MANAGE_DROPDOWN_SELECTOR);
await click(DELETE_ACTION_SELECTOR);
assert.dom('.rose-notification-body').hasText('Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -116,7 +116,9 @@ module('Acceptance | users | update', function (hooks) {
await fillIn('[name="name"]', 'User name');
await click('[type="submit"]');
assert.dom('.rose-notification-body').hasText('The request was invalid.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.dom('[data-test-error-message-name]').hasText('Name is required.');
});
@@ -4,14 +4,7 @@
*/
import { module, test } from 'qunit';
import {
visit,
fillIn,
click,
find,
findAll,
currentURL,
} from '@ember/test-helpers';
import { visit, fillIn, click, findAll, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { Response } from 'miragejs';
@@ -137,11 +130,9 @@ module('Acceptance | workers | create', function (hooks) {
await visit(newWorkerURL);
await fillIn('[name="worker_auth_registration_request"]', 'token');
await click('[type="submit"]');
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'rpc error: code = Unknown',
'Displays primary error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('rpc error: code = Unknown');
});
test('users cannot directly navigate to new worker route without proper authorization', async function (assert) {
@@ -4,7 +4,7 @@
*/
import { module, test } from 'qunit';
import { visit, find, click } from '@ember/test-helpers';
import { visit, click } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { Response } from 'miragejs';
@@ -110,6 +110,8 @@ module('Acceptance | workers | delete', function (hooks) {
await visit(urls.worker);
await click(MANAGE_DROPDOWN_TOGGLE);
await click(REMOVE_WORKER_BUTTON);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('Oops.');
});
});
@@ -86,11 +86,9 @@ module('Acceptance | workers | update', function (hooks) {
await click('.rose-form-actions [type="button"]', 'Click edit mode');
await fillIn('[name="name"]', 'Worker Name');
await click('[type="submit"]');
assert.strictEqual(
find('.rose-notification-body').textContent.trim(),
'The request was invalid.',
'Displays primary error message.',
);
assert
.dom('[data-test-toast-notification] .hds-alert__description')
.hasText('The request was invalid.');
assert.strictEqual(
find('[data-test-error-message-name]').textContent.trim(),
'Name is required',
+5 -3
View File
@@ -26,6 +26,8 @@ export const HREF = (url) => `[href="${url}"]`;
export const SIDEBAR_NAV_LINK = (url) => `[title="General"] a[href="${url}"]`;
export const ALERT_TOAST = '[role="alert"]';
export const ALERT_TOAST_BODY = '.rose-notification-body';
export const ALERT_TOAST_DISMISS = '.rose-notification-dismiss';
export const ALERT_TOAST = '[data-test-toast-notification]';
export const ALERT_TOAST_BODY =
'[data-test-toast-notification] .hds-alert__description';
export const ALERT_TOAST_DISMISS =
'[data-test-toast-notification] .hds-dismiss-button';
+1 -1
View File
@@ -17,7 +17,7 @@ module.exports = {
// This is often limited by the DOM and we want to order our declarations by our own standard
'no-descending-specificity': null,
// As a team we want to stick to using kebab-case as our keyframe name pattern, but there are some exceptions
// in which we use keyframes from addons like ember-botify, HDS or other in which they use other naming style.
// in which we use keyframes from addons like ember-notify, HDS or other in which they use other naming style.
// This regex checks for these patterns and won't fail.
'keyframes-name-pattern': [
'(hds-)|(ember-notify-)|(^gradient)|(^fadeBackground)',
@@ -1,27 +0,0 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
<Rose::Dialog
class='dialog-detail'
@heading={{@heading}}
@dismiss={{@dismiss}}
@dismissButtonText={{@dismissButtonText}}
@modal={{true}}
as |dialog|
>
{{#if @notification}}
<Rose::Notification
@style={{@notificationStyle}}
@heading={{@notification}}
/>
{{/if}}
<dialog.body>
{{yield to='body'}}
</dialog.body>
<dialog.footer>
{{yield to='footer'}}
</dialog.footer>
</Rose::Dialog>
+16 -28
View File
@@ -6,62 +6,57 @@
// This file is essentially a rip of the default ember notify styles with some minor tweaks for positioning.
// sass-lint:disable no-vendor-prefixes
@-webkit-keyframes 'ember-notify-show' {
@-webkit-keyframes ember-notify-show {
from {
left: -310px;
right: -310px;
}
to {
left: 0;
right: 0;
}
}
@keyframes 'ember-notify-show' {
@keyframes ember-notify-show {
from {
left: -310px;
right: -310px;
}
to {
left: 0;
right: 0;
}
}
@-webkit-keyframes 'ember-notify-hide' {
@-webkit-keyframes ember-notify-hide {
from {
left: 0;
right: 0;
}
to {
left: -310px;
right: -310px;
}
}
@keyframes 'ember-notify-hide' {
@keyframes ember-notify-hide {
from {
left: 0;
right: 0;
}
to {
left: -310px;
right: -310px;
}
}
.ember-notify-cn {
bottom: 0;
left: 0;
max-width: 300px;
right: 0;
position: fixed;
z-index: 5000;
margin-bottom: 16px;
}
.ember-notify {
box-sizing: border-box;
display: block;
margin: 10px;
margin: 16px 24px;
position: relative;
width: 300px;
.close {
cursor: pointer;
float: right;
}
width: 360px;
}
.ember-notify-show {
@@ -89,14 +84,7 @@
}
@media only screen and (width <= 680px) {
.ember-notify-cn {
box-sizing: border-box;
padding-left: 20px;
width: 100%;
}
.ember-notify {
float: right;
width: 100%;
}
}
-40
View File
@@ -278,46 +278,6 @@
text-align: center;
}
// Dialog Detail
// These styles are a Work In Progress. Expect changes (lots of them)
.rose-dialog,
.dialog-detail {
z-index: 6000;
}
.dialog-detail {
.rose-notification {
border-left: 0;
border-right: 0;
border-top: 0;
box-shadow: none;
margin-bottom: 0;
}
.rose-dialog-body {
> :first-child {
margin-top: 0;
padding-top: 0;
}
}
.rose-dialog-footer {
align-items: center;
div:nth-child(1) {
display: flex;
justify-content: flex-start;
width: 50%;
}
div:nth-child(2) {
display: flex;
justify-content: flex-end;
width: 50%;
}
}
}
// Overlay above everything - including notifications
.rose-dialog-modal-overlay {
z-index: 5500;
+10 -13
View File
@@ -67,21 +67,18 @@
</Rose::Layout::Global>
{{#if this.flashMessages.queue}}
<div class='ember-notify-cn ember-notify-default'>
<div class='ember-notify-cn'>
{{#each this.flashMessages.queue as |flash|}}
<div
class='ember-notify-show callout
{{flash.notificationType}}
ember-view ember-notify clearfix'
>
<Rose::Notification
@style={{flash.notificationType}}
@heading={{t (concat 'states.' flash.notificationType)}}
@dismiss={{fn flash.dismiss flash}}
@dismissText={{t 'actions.dismiss'}}
<div class='ember-notify-show ember-notify'>
<Hds::Toast
@color={{map-type-to-color flash.notificationType}}
@onDismiss={{fn flash.dismiss flash}}
data-test-toast-notification
as |T|
>
{{flash.message}}
</Rose::Notification>
<T.Title>{{t (concat 'states.' flash.notificationType)}}</T.Title>
<T.Description>{{flash.message}}</T.Description>
</Hds::Toast>
</div>
{{/each}}
</div>
@@ -160,7 +160,9 @@ module('Acceptance | authentication', function (hooks) {
assert.notOk(currentSession().isAuthenticated);
await fillIn('[name="identification"]', 'error');
await click('[type="submit"]');
assert.ok(find('.rose-notification.is-error'));
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
assert.notOk(currentSession().isAuthenticated);
});
@@ -156,7 +156,9 @@ module('Acceptance | clusterUrl', function (hooks) {
await visit(urls.clusterUrl);
await fillIn('[name="host"]', currentOrigin);
await click('[type="submit"]');
assert.ok(find('.rose-notification.is-error'));
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
});
test('clusterUrl set automatically when autoOrigin is true', async function (assert) {
@@ -333,7 +333,9 @@ module('Acceptance | projects | sessions | index', function (hooks) {
await click(`[href="${urls.sessions}"]`);
await click('tbody tr:first-child td:last-child button');
assert.dom('[role="alert"].is-success').isVisible();
assert
.dom('[data-test-toast-notification].hds-alert--color-success')
.isVisible();
});
test('cancelling a session keeps you on the sessions list screen', async function (assert) {
@@ -353,7 +355,9 @@ module('Acceptance | projects | sessions | index', function (hooks) {
await click(`[href="${urls.sessions}"]`);
await click('tbody tr:first-child td:last-child button');
assert.dom('[role="alert"].is-error').isVisible();
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
});
test('cancelling a session with ipc error shows notification', async function (assert) {
@@ -363,7 +367,9 @@ module('Acceptance | projects | sessions | index', function (hooks) {
await click(`[href="${urls.sessions}"]`);
await click('tbody tr:first-child td:last-child button');
assert.dom('[role="alert"].is-error').isVisible();
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
});
test('user can change org scope and only sessions for that org will be displayed', async function (assert) {
@@ -217,7 +217,9 @@ module('Acceptance | projects | sessions | session', function (hooks) {
await visit(urls.session);
await click('[data-test-session-detail-cancel-button]');
assert.dom('[role="alert"].is-success').isVisible();
assert
.dom('[data-test-toast-notification].hds-alert--color-success')
.isVisible();
});
test('cancelling a session takes you to the targets list screen', async function (assert) {
@@ -236,7 +238,9 @@ module('Acceptance | projects | sessions | session', function (hooks) {
await visit(urls.session);
await click('[data-test-session-detail-cancel-button]');
assert.dom('[role="alert"].is-error').isVisible();
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
});
test('cancelling a session with ipc error shows notification', async function (assert) {
@@ -246,6 +250,8 @@ module('Acceptance | projects | sessions | session', function (hooks) {
await visit(urls.session);
await click('[data-test-session-detail-cancel-button]');
assert.dom('[role="alert"].is-error').isVisible();
assert
.dom('[data-test-toast-notification].hds-alert--color-critical')
.isVisible();
});
});
@@ -1,36 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | dialog-detail', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<DialogDetail />`);
assert.ok(find('.dialog-detail'));
});
test('it renders with content', async function (assert) {
this.set('value', 'Test');
await render(hbs`
<DialogDetail as |dialogDetail|>
<dialogDetail.notification />
<dialogDetail.body>
<h2>{{this.value}}</h2>
</dialogDetail.body>
<dialogDetail.footer></dialogDetail.footer>
</DialogDetail>
`);
assert.ok(find('.dialog-detail'));
assert.ok(find('.rose-dialog-header'));
assert.ok(find('.rose-dialog-body'));
assert.ok(find('.rose-dialog-footer'));
});
});