[UI] Remaining page headers update (#11650) (#11707)

* Update page headers that were missed in other prs

* VAULT-40928 replication headers

* VAULT-40926 swagger ui page header

* VAULT-40921 remaining core pageheader

* VAULT-40929 sync headeres

* Fix replication tests

* Fix tests!

* Fix eslint error

* Fix mislabel

* Add badge selector

* Fix failing tests

Co-authored-by: Kianna <30884335+kiannaquach@users.noreply.github.com>
This commit is contained in:
Vault Automation 2026-01-12 07:55:04 -08:00 committed by GitHub
parent c98c3d6d35
commit a78fd4e78c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 198 additions and 224 deletions

View file

@ -3,9 +3,8 @@
SPDX-License-Identifier: BUSL-1.1
}}
<Hds::PageHeader class="has-top-margin-xl has-bottom-margin-m" as |PH|>
<PH.Title>Raft Storage</PH.Title>
<PH.Actions>
<Page::Header @title="Raft Storage">
<:actions>
<Hds::Dropdown as |dd|>
<dd.ToggleButton @text="Snapshots" @color="secondary" />
{{#if this.useServiceWorker}}
@ -19,8 +18,8 @@
{{/if}}
<dd.Interactive @route="vault.cluster.storage-restore">Restore</dd.Interactive>
</Hds::Dropdown>
</PH.Actions>
</Hds::PageHeader>
</:actions>
</Page::Header>
<Hds::Table @caption="Raft servers">
<:head as |H|>

View file

@ -4,8 +4,8 @@
}}
<div {{did-insert this.createKvData @model}}>
<PageHeader as |p|>
<p.top>
<Page::Header @title={{if (eq @mode "create") "Create Secret" (if (eq @mode "edit") "Edit Secret" @key.id)}}>
<:breadcrumbs>
<KeyValueHeader
@baseKey={{@baseKey}}
@path="vault.cluster.secrets.backend.list"
@ -13,20 +13,9 @@
@root={{@root}}
@showCurrent={{true}}
/>
</p.top>
<p.levelLeft>
<h1 class="title is-3">
{{#if (eq @mode "create")}}
Create Secret
{{else if (eq @mode "edit")}}
Edit Secret
{{else}}
{{@key.id}}
<Hds::Copy::Button @isIconOnly={{true}} @text="Copy your secret path" @textToCopy={{@key.id}} />
{{/if}}
</h1>
</p.levelLeft>
</PageHeader>
</:breadcrumbs>
</Page::Header>
{{! tabs for show only }}
{{#if (eq @mode "show")}}
<div class="tabs-container box is-bottomless is-marginless is-fullwidth is-paddingless">

View file

@ -3,27 +3,26 @@
SPDX-License-Identifier: BUSL-1.1
}}
<PageHeader data-test-replication-header as |p|>
<p.top>
<Page::Header @title={{@title}}>
<:breadcrumbs>
{{#if (not (or @isSummaryDashboard @isSecondary))}}
<Hds::Breadcrumb>
<Hds::Breadcrumb::Item @text="Replication" @route="vault.cluster.replication.index" />
<Hds::Breadcrumb::Item @text={{@title}} @current={{true}} />
</Hds::Breadcrumb>
<Page::Breadcrumbs
@breadcrumbs={{array (hash label="Replication" route="vault.cluster.replication.index") (hash label=@title)}}
/>
{{/if}}
</p.top>
<p.levelLeft>
<h1 class="title is-3" data-test-replication-title={{@title}}>
{{@title}}
{{#if @data.anyReplicationEnabled}}
<Hds::Badge @text={{if @isSecondary "secondary" "primary"}} data-test-mode />
{{#if @secondaryId}}
<Hds::Badge @text={{@secondaryId}} data-test-secondaryId />
{{/if}}
</:breadcrumbs>
<:badges>
{{#if @data.anyReplicationEnabled}}
<Hds::Badge
@text={{if @isSecondary "secondary" "primary"}}
data-test-badge={{if @isSecondary "secondary" "primary"}}
/>
{{#if @secondaryId}}
<Hds::Badge @text={{@secondaryId}} data-test-badge={{@secondaryId}} />
{{/if}}
</h1>
</p.levelLeft>
</PageHeader>
{{/if}}
</:badges>
</Page::Header>
{{#if @showTabs}}
<div class="tabs-container box is-bottomless is-fullwidth is-paddingless has-bottom-margin-l" data-test-tabs>

View file

@ -4,32 +4,16 @@
}}
{{#let (options-for-backend this.effectiveEngineType) as |options|}}
<PageHeader as |p|>
<p.top>
<Hds::Breadcrumb>
<Hds::Breadcrumb::Item @text="Secrets" @route="vault.cluster.secrets" data-test-breadcrumb="Secrets" />
<Hds::Breadcrumb::Item
@text={{@model.id}}
@current={{not @isConfigure}}
@route="vault.cluster.secrets.backend.list-root"
@model={{@model.id}}
/>
{{#if @isConfigure}}
<Hds::Breadcrumb::Item @text="Configure" @current={{true}} />
{{/if}}
</Hds::Breadcrumb>
</p.top>
<p.levelLeft>
<h1 class="title is-3">
<Icon @name={{@model.icon}} @size="24" class="has-text-grey-light" />
{{@model.id}}
{{#if this.isKV}}
<Hds::Badge @text="version {{or @model.version '1'}}" data-test-kv-version-badge />
{{/if}}
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title={{@model.id}} @icon={{@model.icon}}>
<:breadcrumbs>
<Page::Breadcrumbs @breadcrumbs={{this.breadcrumbs}} />
</:breadcrumbs>
<:badges>
{{#if this.isKV}}
<Hds::Badge @text="version {{or @model.version '1'}}" data-test-badge="kv version" />
{{/if}}
</:badges>
</Page::Header>
{{#if options.tabs}}
<div class="tabs-container box is-bottomless is-marginless is-fullwidth is-paddingless">

View file

@ -23,6 +23,26 @@ import { getEffectiveEngineType } from 'vault/utils/external-plugin-helpers';
*/
export default class SecretListHeader extends Component {
get breadcrumbs() {
const breadcrumbs = [
{ label: 'Secrets', route: 'vault.cluster.secrets' },
{
label: this.args.model.id,
route: 'vault.cluster.secrets.backend.list-root',
model: this.args.model.id,
current: !this.args.isConfigure,
},
];
if (this.args.isConfigure) {
breadcrumbs.push([{ label: 'Configure' }]);
return breadcrumbs;
}
return breadcrumbs;
}
get effectiveEngineType() {
return getEffectiveEngineType(this.args.model.engineType);
}

View file

@ -3,13 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
}}
<PageHeader as |p|>
<p.levelLeft>
<h1 class="title is-3">
{{this.title}}
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title={{this.title}} />
<EmptyState
@title="Upgrade to use {{this.featureName}}"

View file

@ -3,16 +3,11 @@
SPDX-License-Identifier: BUSL-1.1
}}
<PageHeader as |p|>
<p.top>
<Page::Header @title={{if this.credentials "Credentials" "Generate credentials"}}>
<:breadcrumbs>
<Page::Breadcrumbs @breadcrumbs={{@breadcrumbs}} />
</p.top>
<p.levelLeft>
<h1 class="title is-3 has-bottom-margin-2" data-test-credentials-header>
{{if this.credentials "Credentials" "Generate credentials"}}
</h1>
</p.levelLeft>
</PageHeader>
</:breadcrumbs>
</Page::Header>
{{#if this.credentials}}
<div class="box is-sideless is-fullwidth is-marginless has-bottom-padding-l" data-test-credentials-details>

View file

@ -3,13 +3,7 @@
SPDX-License-Identifier: BUSL-1.1
}}
<PageHeader as |p|>
<p.levelLeft>
<h1 class="title is-3">
API Explorer
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title="API Explorer" />
<div class="box is-fullwidth is-sideless is-marginless">
<NamespaceReminder as |R|>

View file

@ -4,20 +4,8 @@
}}
{{#if @replicationDisabled}}
<PageHeader as |p|>
<p.levelLeft>
<h1 class="title is-3" data-test-replication-title={{@replicationMode}}>
{{#if (eq @replicationMode "dr")}}
Enable Disaster Recovery Replication
{{else if (eq @replicationMode "performance")}}
Enable Performance Replication
{{else}}
{{! should never get here, but have safe fallback just in case }}
Enable Replication
{{/if}}
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title={{this.title}} />
<div class="box is-sideless is-fullwidth is-marginless">
{{#if (eq @replicationMode "dr")}}
<h2 class="title is-flex-center is-5 is-marginless">

View file

@ -22,6 +22,17 @@ import Component from '@glimmer/component';
* @param {string} replicationMode - should be "dr" or "performance"
*/
export default class PageModeIndex extends Component {
get title() {
if (this.args.replicationMode === 'dr') {
return 'Enable Disaster Recovery Replication';
}
if (this.args.replicationMode === 'performance') {
return 'Enable Performance Replication';
}
// should never get here, but have safe fallback just in case
return 'Enable Replication';
}
canEnable = (type) => {
const { cluster, replicationMode } = this.args;
let perm;

View file

@ -7,24 +7,14 @@
<div class="container is-widescreen">
{{#if (eq this.model.mode "unsupported")}}
{{! Replication is unsupported in non-enterprise or when using non-transactional storage (eg inmem) }}
<PageHeader as |p|>
<p.levelLeft>
<h1 class="title is-3 has-text-grey" data-test-replication-title="Replication unsupported">
Replication unsupported
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title="Replication unsupported" />
<EmptyState @title="The current cluster configuration does not support replication" />
{{else if this.model.replicationIsInitializing}}
<LayoutLoading />
{{else if this.model.allReplicationDisabled}}
<PageHeader as |p|>
<p.levelLeft>
<h1 class="title is-3" data-test-replication-title="Enable Replication">
Enable Replication
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title="Enable Replication" />
<div class="box is-sideless is-fullwidth is-marginless">
<p class="has-text-grey-dark box is-shadowless is-fullwidth has-slim-padding">
<label for="replication-mode" class="is-label is-block">
@ -112,13 +102,7 @@
</ReplicationPage>
{{else}}
{{! Renders when at least one mode is not enabled }}
<PageHeader as |p|>
<p.levelLeft>
<h1 class="title is-3" data-test-replication-title="Replication">
Replication
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title="Replication" />
<div class="box is-sideless is-fullwidth is-marginless flex-col">
<ReplicationOverviewMode

View file

@ -9,20 +9,23 @@
<LayoutLoading />
{{else}}
{{#if this.model.replicationAttrs.replicationEnabled}}
<PageHeader as |p|>
<p.top>
<Hds::Breadcrumb>
<Hds::Breadcrumb::Item @text="Replication" @route="index" data-test-replication-breadcrumb />
<Hds::Breadcrumb::Item @text={{this.model.replicationModeForDisplay}} @current={{true}} />
</Hds::Breadcrumb>
</p.top>
<p.levelLeft>
<h1 class="has-top-margin-m title is-3" data-test-replication-title={{this.model.replicationModeForDisplay}}>
{{this.model.replicationModeForDisplay}}
<Hds::Badge @text={{this.model.replicationAttrs.modeForHeader}} data-test-replication-mode-display />
</h1>
</p.levelLeft>
</PageHeader>
<Page::Header @title={{this.model.replicationModeForDisplay}}>
<:breadcrumbs>
<Page::Breadcrumbs
@breadcrumbs={{array
(hash label="Replication" route="index")
(hash label=this.model.replicationModeForDisplay)
}}
/>
</:breadcrumbs>
<:badges>
<Hds::Badge
@text={{this.model.replicationAttrs.modeForHeader}}
data-test-badge={{this.model.replicationAttrs.modeForHeader}}
/>
</:badges>
</Page::Header>
<div class="tabs-container box is-bottomless is-fullwidth is-paddingless is-marginless">
<nav class="tabs sub-nav" aria-label="tab navigation">
<ul>

View file

@ -3,14 +3,19 @@
SPDX-License-Identifier: BUSL-1.1
}}
<SyncHeader @title="Secrets Sync">
<Page::Header @title="Secrets Sync">
<:badges>
{{#if this.flags.isHvdManaged}}
<Hds::Badge @text="Plus feature" @color="highlight" @size="large" data-test-badge="Plus feature" />
{{/if}}
</:badges>
<:actions>
{{! Only allow users who have activated the feature to create a destination. }}
{{#if @isActivated}}
<Hds::Button @text="Create first destination" @route="secrets.destinations.create" data-test-cta-button />
{{/if}}
</:actions>
</SyncHeader>
</Page::Header>
<div class="box is-fullwidth is-sideless is-flex-between is-shadowless" data-test-cta-container>
{{! One cta message regardless of OSS vs Enterprise with/without secrets sync or managed cluster. }}

View file

@ -0,0 +1,17 @@
/**
* Copyright IBM Corp. 2016, 2025
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { service } from '@ember/service';
import type FlagsService from 'vault/services/flags';
interface Args {
isActivated: boolean;
}
export default class LandingCtaComponent extends Component<Args> {
@service declare readonly flags: FlagsService;
}

View file

@ -3,26 +3,15 @@
SPDX-License-Identifier: BUSL-1.1
}}
<PageHeader as |p|>
{{#if @breadcrumbs}}
<p.top>
<Page::Header @title={{@title}} @icon={{@icon}}>
<:breadcrumbs>
{{#if @breadcrumbs}}
<Page::Breadcrumbs @breadcrumbs={{@breadcrumbs}} />
</p.top>
{{/if}}
<p.levelLeft>
<h1 class="title is-3 has-bottom-margin-m" data-test-page-title>
{{#if @icon}}
<Icon @name={{@icon}} @size="24" />
{{/if}}
{{@title}}
{{#if this.flags.isHvdManaged}}
<Hds::Badge @text="Plus feature" @color="highlight" @size="large" />
{{/if}}
</h1>
</p.levelLeft>
<p.levelRight>
{{yield to="actions"}}
</p.levelRight>
</PageHeader>
{{/if}}
</:breadcrumbs>
<:badges>
{{#if this.flags.isHvdManaged}}
<Hds::Badge @text="Plus feature" @color="highlight" @size="large" data-test-badge="Plus feature" />
{{/if}}
</:badges>
</Page::Header>

View file

@ -143,7 +143,7 @@ module('Acceptance | Enterprise | replication-secondaries', function (hooks) {
'Promote this cluster to a Disaster Recovery primary',
'shows the correct description for a DR secondary'
);
assert.dom('[data-test-mode]').includesText('secondary', 'shows the DR secondary mode badge');
assert.dom(GENERAL.badge('secondary')).includesText('secondary', 'shows the DR secondary mode badge');
await click(GENERAL.linkTo('Details'));
assert

View file

@ -21,10 +21,9 @@ const s = {
};
// wait for specific title selector as an attempt to stabilize flaky tests
async function assertTitle(assert, title, altSelector) {
const selector = altSelector || title;
await waitFor(s.title(selector));
assert.dom(s.title(selector)).hasText(title);
async function assertTitle(assert, title) {
await waitFor(GENERAL.hdsPageHeaderTitle);
assert.dom(GENERAL.hdsPageHeaderTitle).hasText(title);
}
module('Acceptance | Enterprise | replication modes', function (hooks) {
@ -124,7 +123,8 @@ module('Acceptance | Enterprise | replication modes', function (hooks) {
assert.dom(s.enableForm).exists('it shows the enable view for performance');
await click(GENERAL.navLink('Disaster Recovery'));
await assertTitle(assert, 'Disaster Recovery primary', 'Disaster Recovery');
await assertTitle(assert, 'Disaster Recovery', 'Disaster Recovery');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for dr');
assert.dom(s.dashboard).exists(`it shows the replication dashboard`);
});
@ -134,15 +134,18 @@ module('Acceptance | Enterprise | replication modes', function (hooks) {
performance: mockReplicationBlock('primary'),
});
await visit('/vault/replication');
await assertTitle(assert, 'Disaster Recovery & Performance primary', 'Disaster Recovery & Performance');
await assertTitle(assert, 'Disaster Recovery & Performance', 'Disaster Recovery & Performance');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for dr');
assert.dom(s.summaryCard).exists({ count: 2 }, 'shows 2 summary cards');
await click(GENERAL.navLink('Performance'));
await assertTitle(assert, 'Performance primary', 'Performance');
await assertTitle(assert, 'Performance', 'Performance');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for dr');
assert.dom(s.enableForm).doesNotExist();
await click(GENERAL.navLink('Disaster Recovery'));
await assertTitle(assert, 'Disaster Recovery primary', 'Disaster Recovery');
await assertTitle(assert, 'Disaster Recovery', 'Disaster Recovery');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for dr');
assert.dom(s.enableForm).doesNotExist();
});
});

View file

@ -39,11 +39,9 @@ module('Acceptance | Enterprise | replication', function (hooks) {
await pollCluster(this.owner);
await settled();
assert
.dom('[data-test-replication-title="Disaster Recovery"]')
.dom(GENERAL.hdsPageHeaderTitle)
.includesText('Disaster Recovery', 'it displays the replication type correctly');
assert
.dom('[data-test-replication-mode-display]')
.includesText('primary', 'it displays the cluster mode correctly');
assert.dom(GENERAL.badge('primary')).includesText('primary', 'it displays the cluster mode correctly');
await addSecondary(secondaryName);
// modal for copying the token appears
@ -258,7 +256,7 @@ module('Acceptance | Enterprise | replication', function (hooks) {
assert.dom('[data-test-replication-dashboard]').exists();
assert.dom('[data-test-selectable-card-container="secondary"]').exists();
assert
.dom('[data-test-replication-mode-display]')
.dom(GENERAL.badge('secondary'))
.hasText('secondary', 'it displays the cluster mode correctly in header');
});
@ -283,10 +281,10 @@ module('Acceptance | Enterprise | replication', function (hooks) {
await settled();
// Breadcrumbs only load once we're in the summary mode after enabling
await waitFor('[data-test-replication-breadcrumb]');
await waitFor(GENERAL.breadcrumb);
// navigate using breadcrumbs back to replication.index
assert.dom('[data-test-replication-breadcrumb]').exists('shows the replication breadcrumb (flaky)');
await click('[data-test-replication-breadcrumb] a');
assert.dom(GENERAL.currentBreadcrumb('Replication')).exists('shows the replication breadcrumb (flaky)');
await click(GENERAL.breadcrumbLink('Replication'));
assert
.dom('[data-test-replication-summary-card]')

View file

@ -31,18 +31,21 @@ module('Acceptance | Enterprise | replication navigation', function (hooks) {
test('navigate between replication types updates page', async function (assert) {
await click(SELECTORS.navReplication);
assert.dom(SELECTORS.title).hasText('Disaster Recovery & Performance primary');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Disaster Recovery & Performance');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for dr');
await click(SELECTORS.navPerformance);
// Ensure data is expected for performance
assert.dom(SELECTORS.title).hasText('Performance primary');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Performance');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for performance');
assert.dom(SELECTORS.primaryCluster).hasText('perf-foobar');
assert.dom(SELECTORS.replicationSet).hasText('perf-cluster-id');
assert.dom(SELECTORS.knownSecondariesTitle).hasText('0 Known secondaries');
// Nav to DR and see updated data
await click(SELECTORS.navDR);
assert.dom(SELECTORS.title).hasText('Disaster Recovery primary');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Disaster Recovery');
assert.dom(GENERAL.badge('primary')).exists('shows primary badge for dr');
assert.dom(SELECTORS.primaryCluster).hasText('dr-foobar');
assert.dom(SELECTORS.replicationSet).hasText('dr-cluster-id');
assert.dom(SELECTORS.knownSecondariesTitle).hasText('1 Known secondaries');

View file

@ -361,7 +361,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
'vault.cluster.secrets.backend.show',
`${path}: show page renders correctly`
);
assert.dom('h1.title').hasText(`${path}/2`, 'shows correct page title');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText(`${path}/2`, 'shows correct page title');
}
});

View file

@ -65,7 +65,7 @@ module('Integration | Component | kubernetes | Page::Credentials', function (hoo
test('it should display generate credentials form', async function (assert) {
await this.renderComponent();
assert.dom('[data-test-credentials-header]').hasText('Generate credentials');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Generate credentials');
assert
.dom('[data-test-generate-credentials] p')
.hasText(`This will generate credentials using the role ${this.roleName}.`);
@ -118,7 +118,7 @@ module('Integration | Component | kubernetes | Page::Credentials', function (hoo
this.generateStub.calledWith(this.roleName, this.backend, payload),
'Generate credentials request made'
);
assert.dom('[data-test-credentials-header]').hasText('Credentials');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Credentials');
assert.dom('[data-test-k8-alert-title]').hasText('Warning');
assert
.dom('[data-test-k8-alert-message]')

View file

@ -7,6 +7,7 @@ import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const DATA = {
anyReplicationEnabled: true,
@ -37,7 +38,7 @@ module('Integration | Component | replication-header', function (hooks) {
<ReplicationHeader @data={{this.data}} @isSecondary={{this.isSecondary}} @title={{this.title}}/>
`);
assert.dom('[data-test-replication-header]').exists();
assert.dom(GENERAL.hdsPageHeaderTitle).exists();
});
test('it renders with mode and secondaryId when set', async function (assert) {
@ -45,8 +46,8 @@ module('Integration | Component | replication-header', function (hooks) {
<ReplicationHeader @data={{this.data}} @isSecondary={{this.isSecondary}} @title={{this.title}} @secondaryId={{this.secondaryId}}/>
`);
assert.dom('[data-test-secondaryId]').includesText(SECONDARY_ID, `shows the correct secondaryId value`);
assert.dom('[data-test-mode]').includesText('secondary', `shows the correct mode value`);
assert.dom(GENERAL.badge(SECONDARY_ID)).includesText(SECONDARY_ID, `shows the correct secondaryId value`);
assert.dom(GENERAL.badge('secondary')).includesText('secondary', `shows the correct mode value`);
});
test('it does not render mode or secondaryId when replication is not enabled', async function (assert) {
@ -60,7 +61,7 @@ module('Integration | Component | replication-header', function (hooks) {
`);
assert.dom('[data-test-secondaryId]').doesNotExist();
assert.dom('[data-test-mode]').doesNotExist();
assert.dom(GENERAL.badge('secondary')).doesNotExist();
});
test('it does not show tabs when showTabs is not set', async function (assert) {

View file

@ -8,6 +8,7 @@ import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
module('Integration | Component | replication-page', function (hooks) {
setupRenderingTest(hooks);
@ -60,13 +61,13 @@ module('Integration | Component | replication-page', function (hooks) {
await render(
hbs`<ReplicationPage @model={{this.model}} as |Page|><Page.header @showTabs={{false}} /></ReplicationPage>`
);
assert.dom('[data-test-replication-title="Disaster Recovery"]').hasText('Disaster Recovery');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Disaster Recovery');
this.model.replicationMode = 'performance';
await render(
hbs`<ReplicationPage @model={{this.model}} as |Page|><Page.header @showTabs={{false}} /></ReplicationPage>`
);
assert.dom('[data-test-replication-title="Performance"]').hasText('Performance');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Performance');
});
});

View file

@ -9,6 +9,7 @@ import { getContext, render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { supportedSecretBackends } from 'vault/helpers/supported-secret-backends';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const mirageToModels = (data) => {
const context = getContext();
@ -39,17 +40,18 @@ module('Integration | Component | secret-list-header', function (hooks) {
@model={{this.model}}
/>
`);
const selector = '[data-test-kv-version-badge]';
if (['kv', 'generic'].includes(type)) {
assert
.dom(selector)
.dom(GENERAL.badge('kv version'))
.hasText(
`version ${this.model.version || 1}`,
`Badge renders with correct version for ${type} engine type`
);
} else {
assert.dom(selector).doesNotExist(`Version badge does not render for ${type} engine type`);
assert
.dom(GENERAL.badge('kv version'))
.doesNotExist(`Version badge does not render for ${type} engine type`);
}
}
});

View file

@ -12,6 +12,7 @@ import hbs from 'htmlbars-inline-precompile';
import { click, fillIn, render } from '@ember/test-helpers';
import { PAGE } from 'vault/tests/helpers/sync/sync-selectors';
import sinon from 'sinon';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
module('Integration | Component | sync | Secrets::DestinationHeader', function (hooks) {
setupRenderingTest(hooks);
@ -33,7 +34,7 @@ module('Integration | Component | sync | Secrets::DestinationHeader', function (
test('it should render SyncHeader component', async function (assert) {
await this.renderComponent();
assert.dom(PAGE.title).includesText('destination-aws', 'SyncHeader component renders');
assert.dom(GENERAL.hdsPageHeaderTitle).includesText('destination-aws', 'SyncHeader component renders');
});
test('it should render tabs', async function (assert) {

View file

@ -14,7 +14,7 @@ import sinon from 'sinon';
import { PAGE } from 'vault/tests/helpers/sync/sync-selectors';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const { title, tab, filter, searchSelect, emptyStateTitle, destinations, confirmButton } = PAGE;
const { tab, filter, searchSelect, emptyStateTitle, destinations, confirmButton } = PAGE;
module('Integration | Component | sync | Page::Destinations', function (hooks) {
setupRenderingTest(hooks);
@ -64,7 +64,7 @@ module('Integration | Component | sync | Page::Destinations', function (hooks) {
test('it should render header and tabs', async function (assert) {
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync', 'Page title renders');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Secrets Sync', 'Page title renders');
assert.dom(tab('Overview')).exists('Overview tab renders');
assert.dom(tab('Destinations')).exists('Destinations tab renders');
});

View file

@ -267,7 +267,7 @@ module('Integration | Component | sync | Secrets::Page::Destinations::CreateAndE
await this.renderComponent();
assert.dom(PAGE.title).hasTextContaining(`Create Destination for ${name}`);
assert.dom(GENERAL.hdsPageHeaderTitle).hasTextContaining(`Create Destination for ${name}`);
for (const field of this.formFields) {
assert.dom(PAGE.fieldByAttr(field.name)).exists();
@ -401,7 +401,7 @@ module('Integration | Component | sync | Secrets::Page::Destinations::CreateAndE
await this.renderComponent(false, type);
assert.dom(PAGE.title).hasTextContaining(`Edit ${this.form.name}`);
assert.dom(GENERAL.hdsPageHeaderTitle).hasTextContaining(`Edit ${this.form.name}`);
for (const field of this.formFields) {
if (editable.includes(field.name)) {

View file

@ -13,6 +13,7 @@ import { PAGE } from 'vault/tests/helpers/sync/sync-selectors';
import { syncDestinations, findDestination } from 'vault/helpers/sync-destinations';
import { toLabel } from 'vault/helpers/to-label';
import { setupDataStubs } from 'vault/tests/helpers/sync/setup-hooks';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const SYNC_DESTINATIONS = syncDestinations();
module(
@ -119,7 +120,7 @@ module(
assert
.dom(PAGE.destinations.details.sectionHeader)
.doesNotExist('does not render Custom tags header');
assert.dom(PAGE.title).hasTextContaining(this.destination.name);
assert.dom(GENERAL.hdsPageHeaderTitle).hasTextContaining(this.destination.name);
assert.dom(PAGE.icon(findDestination(destination.type).icon)).exists();
assert.dom(PAGE.infoRowValue('Name')).hasText(this.destination.name);

View file

@ -15,6 +15,7 @@ import sinon from 'sinon';
import { Response } from 'miragejs';
import { PAGE } from 'vault/tests/helpers/sync/sync-selectors';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
module(
'Integration | Component | sync | Secrets::Page::Destinations::Destination::Secrets',
@ -41,7 +42,9 @@ module(
});
test('it should render DestinationHeader component', async function (assert) {
assert.dom(PAGE.title).includesText('destination-aws', 'DestinationHeader component renders');
assert
.dom(GENERAL.hdsPageHeaderTitle)
.includesText('destination-aws', 'DestinationHeader component renders');
});
test('it should render empty list state', async function (assert) {

View file

@ -18,8 +18,9 @@ import { Response } from 'miragejs';
import { dateFormat } from 'core/helpers/date-format';
import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs';
import { listDestinationsTransform } from 'sync/utils/api-transforms';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const { title, tab, overviewCard, cta, overview, emptyStateTitle, emptyStateMessage } = PAGE;
const { tab, overviewCard, cta, overview, emptyStateTitle, emptyStateMessage } = PAGE;
module('Integration | Component | sync | Page::Overview', function (hooks) {
setupRenderingTest(hooks);
@ -94,7 +95,7 @@ module('Integration | Component | sync | Page::Overview', function (hooks) {
});
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync', 'Page title renders');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Secrets Sync', 'Page title renders');
assert.dom(cta.summary).doesNotExist('CTA does not render');
assert.dom(tab('Overview')).hasText('Overview', 'Overview tab renders');
assert.dom(tab('Destinations')).hasText('Destinations', 'Destinations tab renders');
@ -114,7 +115,8 @@ module('Integration | Component | sync | Page::Overview', function (hooks) {
await this.renderComponent();
assert.dom(overview.optInBanner.container).doesNotExist('Opt-in banner is not shown');
assert.dom(title).hasText('Secrets Sync Plus feature');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Secrets Sync');
assert.dom(GENERAL.badge('Plus feature')).hasText('Plus feature', 'Plus feature badge renders');
assert.dom(cta.button).hasText('Create first destination', 'CTA action renders');
assert.dom(cta.summary).exists();
});
@ -156,7 +158,7 @@ module('Integration | Component | sync | Page::Overview', function (hooks) {
this.isActivated = true;
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Secrets Sync');
assert.dom(cta.button).hasText('Create first destination', 'CTA action renders');
assert.dom(cta.summary).exists();
});

View file

@ -9,8 +9,9 @@ import { setupEngine } from 'ember-engines/test-support';
import hbs from 'htmlbars-inline-precompile';
import { render } from '@ember/test-helpers';
import { PAGE } from 'vault/tests/helpers/sync/sync-selectors';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const { title, breadcrumb } = PAGE;
const { breadcrumb } = PAGE;
module('Integration | Component | sync | SyncHeader', function (hooks) {
setupRenderingTest(hooks);
@ -42,7 +43,7 @@ module('Integration | Component | sync | SyncHeader', function (hooks) {
this.version.features = ['Secrets Sync'];
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Secrets Sync');
});
});
@ -54,22 +55,8 @@ module('Integration | Component | sync | SyncHeader', function (hooks) {
test('it should render title and plus badge', async function (assert) {
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync Plus feature');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Secrets Sync');
assert.dom(GENERAL.badge('Plus feature')).hasText('Plus feature', 'Plus feature badge renders');
});
});
test('it should yield actions block', async function (assert) {
await render(
hbs`
<SyncHeader @title={{this.title}} @breadcrumbs={{this.breadcrumbs}}>
<:actions>
<span data-test-action-block>Test</span>
</:actions>
</SyncHeader>
`,
{ owner: this.engine }
);
assert.dom('[data-test-action-block]').exists('Component yields block for actions');
});
});

View file

@ -7,6 +7,7 @@ import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
module('Integration | Component | upgrade page', function (hooks) {
setupRenderingTest(hooks);
@ -16,7 +17,7 @@ module('Integration | Component | upgrade page', function (hooks) {
{{upgrade-page}}
`);
assert.dom('.page-header .title').hasText('Vault Enterprise', 'renders default page title');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Vault Enterprise', 'renders default page title');
assert
.dom('[data-test-empty-state-title]')
.hasText('Upgrade to use this feature', 'renders default title');
@ -34,7 +35,7 @@ module('Integration | Component | upgrade page', function (hooks) {
{{upgrade-page title="Test Feature Title" minimumEdition="Vault Enterprise Premium"}}
`);
assert.dom('.page-header .title').hasText('Test Feature Title', 'renders custom page title');
assert.dom(GENERAL.hdsPageHeaderTitle).hasText('Test Feature Title', 'renders custom page title');
assert
.dom('[data-test-empty-state-title]')
.hasText('Upgrade to use Test Feature Title', 'renders custom title');