Merge pull request #11513 from marshmalien/10241-test-locator

Add test locators to OUIA-compliant components
This commit is contained in:
Sarah Akus 2022-01-10 13:10:08 -05:00 committed by GitHub
commit 53ff99e391
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 682 additions and 138 deletions

View File

@ -128,6 +128,7 @@ function AdHocCommands({
component="button"
aria-label={t`Run Command`}
onClick={() => setIsWizardOpen(true)}
ouiaId="run-command-dropdown-item"
>
{t`Run Command`}
</DropdownItem>

View File

@ -207,6 +207,7 @@ function AdHocDetailsStep({ verbosityOptions, moduleOptions }) {
onChange={() => {
diffModeHelpers.setValue(!diffModeField.value);
}}
ouiaId="diff-mode-switch"
aria-label={t`toggle changes`}
/>
</FormGroup>
@ -236,6 +237,7 @@ function AdHocDetailsStep({ verbosityOptions, moduleOptions }) {
</span>
}
id="become_enabled"
ouiaId="become_enabled"
isChecked={becomeEnabledField.value}
onChange={(checked) => {
becomeEnabledHelpers.setValue(checked);

View File

@ -42,6 +42,7 @@ function AddDropDownButton({ dropdownItems, ouiaId }) {
/>
}
dropdownItems={dropdownItems}
ouiaId="add-dropdown"
/>
</div>
);

View File

@ -26,6 +26,7 @@ function CheckboxCard(props) {
onChange={onSelect}
aria-label={name}
id={`checkbox-card-${itemId}`}
ouiaId={`checkbox-card-${itemId}`}
label={
<>
<div style={{ fontWeight: 'bold' }}>{name}</div>

View File

@ -77,6 +77,7 @@ function AlertModal({
isOpen={Boolean(isOpen)}
variant="small"
title={title}
ouiaId="alert-modal"
{...props}
>
{children}

View File

@ -31,6 +31,7 @@ function AnsibleSelect({
return (
<FormSelect
id={id}
ouiaId={id}
value={value}
onChange={onSelectChange}
onBlur={onBlur}

View File

@ -91,7 +91,11 @@ function AppContainer({ navRouteConfig = [], children }) {
<PageSidebar
theme="dark"
nav={
<Nav aria-label={t`Navigation`} theme="dark">
<Nav
aria-label={t`Navigation`}
theme="dark"
ouiaId="sidebar-navigation"
>
<NavList>
{navRouteConfig.map(({ groupId, groupTitle, routes }) => (
<NavExpandableGroup

View File

@ -20,7 +20,12 @@ function NavExpandableGroup(props) {
if (routes.length === 1 && groupId === 'settings') {
const [{ path }] = routes;
return (
<NavItem itemId={groupId} isActive={isActivePath(path)} key={path}>
<NavItem
itemId={groupId}
isActive={isActivePath(path)}
key={path}
// ouiaId={path}
>
<Link to={path}>{groupTitle}</Link>
</NavItem>
);
@ -31,10 +36,16 @@ function NavExpandableGroup(props) {
isActive={isActive}
isExpanded
groupId={groupId}
ouiaId={groupId}
title={groupTitle}
>
{routes.map(({ path, title }) => (
<NavItem groupId={groupId} isActive={isActivePath(path)} key={path}>
<NavItem
groupId={groupId}
isActive={isActivePath(path)}
key={path}
// ouiaId={path}
>
<Link to={path}>{title}</Link>
</NavItem>
))}

View File

@ -101,8 +101,13 @@ function PageHeaderToolbar({
isOpen={isHelpOpen}
position={DropdownPosition.right}
onSelect={handleHelpSelect}
ouiaId="toolbar-info-dropdown"
toggle={
<DropdownToggle onToggle={setIsHelpOpen} aria-label={t`Info`}>
<DropdownToggle
onToggle={setIsHelpOpen}
aria-label={t`Info`}
ouiaId="toolbar-info-dropdown-toggle"
>
<QuestionCircleIcon />
</DropdownToggle>
}
@ -111,6 +116,7 @@ function PageHeaderToolbar({
key="help"
target="_blank"
href={`${getDocsBaseUrl(config)}/html/userguide/index.html`}
ouiaId="help-dropdown-item"
>
{t`Help`}
</DropdownItem>,
@ -119,6 +125,7 @@ function PageHeaderToolbar({
component="button"
isDisabled={isAboutDisabled}
onClick={onAboutClick}
ouiaId="about-dropdown-item"
>
{t`About`}
</DropdownItem>,
@ -128,12 +135,16 @@ function PageHeaderToolbar({
<PageHeaderToolsItem>
<Dropdown
id="toolbar-user-dropdown"
ouiaId="toolbar-user-dropdown"
isPlain
isOpen={isUserOpen}
position={DropdownPosition.right}
onSelect={handleUserSelect}
toggle={
<DropdownToggle onToggle={setIsUserOpen}>
<DropdownToggle
onToggle={setIsUserOpen}
ouiaId="toolbar-user-dropdown-toggle"
>
<UserIcon />
{loggedInUser && (
<span style={{ marginLeft: '10px' }}>
@ -149,6 +160,7 @@ function PageHeaderToolbar({
href={
loggedInUser ? `#/users/${loggedInUser.id}/details` : '#/home'
}
ouiaId="user-dropdown-item"
>
{t`User Details`}
</DropdownItem>,
@ -157,6 +169,7 @@ function PageHeaderToolbar({
component="button"
onClick={onLogoutClick}
id="logout-button"
ouiaId="logout-dropdown-item"
>
{t`Logout`}
</DropdownItem>,

View File

@ -44,12 +44,21 @@ const CheckboxListItem = ({
{columns?.length > 0 ? (
columns.map((col) => (
<Td aria-label={col.name} dataLabel={col.key} key={col.key}>
<Td
aria-label={col.name}
data-cy={`item-${itemId}-${col.name}`}
dataLabel={col.key}
key={col.key}
>
{item[col.key]}
</Td>
))
) : (
<Td aria-labelledby={itemId} dataLabel={label}>
<Td
aria-labelledby={itemId}
data-cy={`item-${itemId}`}
dataLabel={label}
>
<b>{label}</b>
</Td>
)}

View File

@ -109,6 +109,7 @@ function VariablesDetail({
<Modal
variant="xlarge"
title={label}
ouiaId={`${dataCy}-modal`}
isOpen={isExpanded}
onClose={() => setIsExpanded(false)}
actions={[

View File

@ -131,6 +131,7 @@ function VariablesField({
<Modal
variant="xlarge"
title={label}
ouiaId={`${id}-modal`}
isOpen={isExpanded}
onClose={() => setIsExpanded(false)}
actions={[
@ -214,7 +215,7 @@ function VariablesFieldInternals({
return (
<div className="pf-c-form__group">
<FieldHeader>
<FieldHeader data-cy={`${id}-label`}>
<Split hasGutter>
<SplitItem>
<label htmlFor={id} className="pf-c-form__label">
@ -246,7 +247,7 @@ function VariablesFieldInternals({
variant="plain"
aria-label={t`Expand input`}
onClick={onExpand}
ouiaId={`${id}-variables-expand`}
ouiaId={`${id}-expand`}
>
<ExpandArrowsAltIcon />
</Button>

View File

@ -80,6 +80,7 @@ function DataListToolbar({
return (
<Toolbar
id={`${qsConfig.namespace}-list-toolbar`}
ouiaId={`${qsConfig.namespace}-list-toolbar`}
clearAllFilters={clearAllFilters}
collapseListedFiltersBreakpoint="lg"
clearFiltersButtonText={Boolean(search) && t`Clear all filters`}
@ -113,6 +114,7 @@ function DataListToolbar({
onChange={onSelectAll}
aria-label={t`Select all`}
id="select-all"
ouiaId="select-all"
/>
</ToolbarItem>
</ToolbarGroup>
@ -177,6 +179,7 @@ function DataListToolbar({
position={dropdownPosition}
isPlain
dropdownItems={additionalControls}
ouiaId="actions-dropdown"
/>
</KebabifiedProvider>
</ToolbarItem>

View File

@ -27,7 +27,7 @@ function FieldWithPrompt({
isDisabled,
}) {
return (
<div className="pf-c-form__group">
<div className="pf-c-form__group" data-cy={`${fieldId}-form-group`}>
<FieldHeader>
<div>
<label className="pf-c-form__label" htmlFor={fieldId}>
@ -45,6 +45,7 @@ function FieldWithPrompt({
id={promptId}
label={t`Prompt on launch`}
name={promptName}
ouiaId={`${promptId}-checkbox`}
/>
</FieldHeader>
{children}

View File

@ -18,6 +18,7 @@ function CheckboxField({
<Checkbox
isDisabled={isDisabled}
aria-label={label}
ouiaId={id}
label={
<span>
{label}

View File

@ -26,6 +26,7 @@ function FormField(props) {
{(type === 'textarea' && (
<FormGroup
fieldId={id}
data-cy={`${id}-form-group`}
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
@ -48,6 +49,7 @@ function FormField(props) {
)) || (
<FormGroup
fieldId={id}
data-cy={`${id}-form-group`}
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}

View File

@ -27,6 +27,7 @@ function FormSubmitError({ error }) {
<Alert
variant="danger"
isInline
ouiaId="form-submit-error-alert"
title={
Array.isArray(errorMessage)
? errorMessage.map((msg) => <div key={msg}>{msg}</div>)

View File

@ -66,6 +66,7 @@ function HostToggle({
!host.summary_fields.user_capabilities.edit
}
onChange={toggleHost}
ouiaId={`host-${host.id}-toggle`}
aria-label={t`Toggle host`}
/>
</Tooltip>

View File

@ -57,6 +57,7 @@ function InstanceToggle({ className, fetchInstances, instance, onToggle }) {
isChecked={isEnabled}
isDisabled={isLoading || !me?.is_superuser}
onChange={toggleInstance}
ouiaId={`host-${instance.id}-toggle`}
aria-label={t`Toggle instance`}
/>
</Tooltip>

View File

@ -115,6 +115,7 @@ function JobListCancelButton({ jobsToCancel, onCancel }) {
component="button"
aria-labelledby="jobs-list-cancel-button"
onClick={toggleModal}
ouiaId="cancel-job-dropdown-item"
>
{cancelJobText}
</DropdownItem>

View File

@ -60,7 +60,7 @@ function JobListItem({
return (
<>
<Tr id={`job-row-${job.id}`}>
<Tr id={`job-row-${job.id}`} ouiaId={`job-row-${job.id}`}>
<Td
expand={{
rowIndex: job.id,
@ -147,7 +147,11 @@ function JobListItem({
</ActionItem>
</ActionsTd>
</Tr>
<Tr isExpanded={isExpanded} id={`expanded-job-row-${job.id}`}>
<Tr
isExpanded={isExpanded}
id={`expanded-job-row-${job.id}`}
ouiaId={`expanded-job-row-${job.id}`}
>
<Td colSpan={2} />
<Td colSpan={showTypeColumn ? 6 : 5}>
<ExpandableRowContent>
@ -235,10 +239,20 @@ function JobListItem({
<Detail
fullWidth
label={t`Credentials`}
dataCy={`job-${job.id}-credentials`}
value={
<ChipGroup numChips={5} totalChips={credentials.length}>
<ChipGroup
numChips={5}
totalChips={credentials.length}
ouiaId={`job-${job.id}-credential-chips`}
>
{credentials.map((c) => (
<CredentialChip key={c.id} credential={c} isReadOnly />
<CredentialChip
credential={c}
isReadOnly
key={c.id}
ouiaId={`credential-${c.id}-chip`}
/>
))}
</ChipGroup>
}
@ -249,9 +263,17 @@ function JobListItem({
fullWidth
label={t`Labels`}
value={
<ChipGroup numChips={5} totalChips={labels.results.length}>
<ChipGroup
numChips={5}
totalChips={labels.results.length}
ouiaId={`job-${job.id}-label-chips`}
>
{labels.results.map((l) => (
<Chip key={l.id} isReadOnly>
<Chip
key={l.id}
isReadOnly
ouiaId={`label-${l.id}-chip`}
>
{l.name}
</Chip>
))}

View File

@ -77,6 +77,7 @@ function ReLaunchDropDown({
aria-label={t`relaunch jobs`}
id={id}
isPrimary
ouiaId="relaunch-job-toggle"
>
{t`Relaunch`}
</DropdownToggle>
@ -98,6 +99,7 @@ function ReLaunchDropDown({
onToggle={onToggle}
aria-label={t`relaunch jobs`}
id={id}
ouiaId="relaunch-job-toggle"
>
<RocketIcon />
</DropdownToggle>

View File

@ -127,6 +127,7 @@ function CredentialsStep({
onClick={() => removeItem(item)}
isReadOnly={!canDelete}
credential={item}
ouiaId={`credential-chip-${item.id}`}
/>
);

View File

@ -186,6 +186,7 @@ function ShowChangesToggle() {
labelOff={t`Off`}
isChecked={field.value}
onChange={helpers.setValue}
ouiaId="prompt-show-changes"
/>
</FormGroup>
);

View File

@ -96,6 +96,7 @@ function ListHeader(props) {
id={`${qsConfig.namespace}-list-toolbar`}
clearAllFilters={handleRemoveAll}
collapseListedFiltersBreakpoint="lg"
ouiaId={`${qsConfig.namespace}-list-toolbar`}
>
<ToolbarContent>
<EmptyStateControlsWrapper>

View File

@ -275,6 +275,7 @@ function HostFilterLookup({
key={name}
numChips={5}
totalChips={chips[key]?.chips?.length || 0}
ouiaId="host-filter-search-chips"
>
{chips[key]?.chips?.map((chip) => (
<Chip key={chip.key} isReadOnly>
@ -296,6 +297,7 @@ function HostFilterLookup({
key={chips[leftoverKey].key}
numChips={5}
totalChips={chips[leftoverKey]?.chips?.length || 0}
ouiaId="host-filter-advanced-search-chips"
>
{chips[leftoverKey]?.chips?.map((chip) => (
<Chip key={chip.key} isReadOnly>

View File

@ -135,6 +135,7 @@ function Lookup(props) {
<Button
aria-label={t`Search`}
id={`${id}-open`}
ouiaId={`${id}-open`}
onClick={() => dispatch({ type: 'TOGGLE_MODAL' })}
variant={ButtonVariant.control}
isDisabled={isLoading || isDisabled}
@ -143,7 +144,11 @@ function Lookup(props) {
</Button>
{multiple ? (
<ChipHolder isDisabled={isDisabled} className="pf-c-form-control">
<ChipGroup numChips={5} totalChips={items.length}>
<ChipGroup
numChips={5}
totalChips={items.length}
ouiaId={`${id}-chips`}
>
{items.map((item) =>
renderItemChip({
item,
@ -156,6 +161,7 @@ function Lookup(props) {
) : (
<TextInput
id={id}
ouiaId={`${id}-input`}
value={typedText}
onChange={(inputValue) => {
setTypedText(inputValue);
@ -175,6 +181,7 @@ function Lookup(props) {
isOpen={isModalOpen}
onClose={closeModal}
description={state?.selectedItems?.length > 0 && modalDescription}
ouiaId={`${id}-modal`}
actions={[
<Button
ouiaId="modal-select-button"

View File

@ -152,6 +152,7 @@ function MultiCredentialsLookup({
isInline
css="margin-bottom: 20px;"
title={t`You cannot select multiple vault credentials with the same vault ID. Doing so will automatically deselect the other with the same vault ID.`}
ouiaId="multi-credentials-lookup-alert"
/>
)}
{credentialTypes && credentialTypes.length > 0 && (

View File

@ -58,6 +58,7 @@ function TagMultiSelect({ onChange, value }) {
isOpen={isExpanded}
typeAheadAriaLabel={t`Select tags`}
noResultsFoundText={t`No results found`}
ouiaId="tag-multiselect"
>
{renderOptions(options)}
</Select>

View File

@ -21,7 +21,10 @@ function NotificationListItem({
showApprovalsToggle,
}) {
return (
<Tr id={`notification-row-${notification.id}`}>
<Tr
id={`notification-row-${notification.id}`}
ouiaId={`notification-row-${notification.id}`}
>
<Td id={`notification-${notification.id}`} dataLabel={t`Name`}>
<Link to={`${detailUrl}`}>
<b>{notification.name}</b>
@ -32,6 +35,7 @@ function NotificationListItem({
<ActionItem visible={showApprovalsToggle}>
<Switch
id={`notification-${notification.id}-approvals-toggle`}
ouiaId={`notification-${notification.id}-approvals-toggle`}
label={t`Approval`}
labelOff={t`Approval`}
isChecked={approvalsTurnedOn}
@ -49,6 +53,7 @@ function NotificationListItem({
<ActionItem visible>
<Switch
id={`notification-${notification.id}-started-toggle`}
ouiaId={`notification-${notification.id}-started-toggle`}
label={t`Start`}
labelOff={t`Start`}
isChecked={startedTurnedOn}
@ -62,6 +67,7 @@ function NotificationListItem({
<ActionItem visible>
<Switch
id={`notification-${notification.id}-success-toggle`}
ouiaId={`notification-${notification.id}-success-toggle`}
label={t`Success`}
labelOff={t`Success`}
isChecked={successTurnedOn}
@ -75,6 +81,7 @@ function NotificationListItem({
<ActionItem visible>
<Switch
id={`notification-${notification.id}-error-toggle`}
ouiaId={`notification-${notification.id}-error-toggle`}
label={t`Failure`}
labelOff={t`Failure`}
isChecked={errorTurnedOn}

View File

@ -38,7 +38,7 @@ export default function HeaderRow({
// empty first Th aligns with checkboxes in table rows
return (
<Thead>
<Tr>
<Tr ouiaId="paginated-table-header-row">
{isExpandable && <Th />}
{isSelectable && <Th />}
{React.Children.map(

View File

@ -128,6 +128,7 @@ function PaginatedTable({
}
onSetPage={handleSetPage}
onPerPageSelect={handleSetPageSize}
ouiaId="top-pagination"
titles={{
paginationTitle: t`Top Pagination`,
}}
@ -165,6 +166,7 @@ function PaginatedTable({
}
onSetPage={handleSetPage}
onPerPageSelect={handleSetPageSize}
ouiaId="bottom-pagination"
/>
) : null}
</>

View File

@ -108,19 +108,33 @@ function PromptDetail({
return (
<>
<DetailList gutter="sm">
<Detail label={t`Name`} value={buildResourceLink(resource)} />
<Detail label={t`Description`} value={details.description} />
<Detail
label={t`Name`}
dataCy="prompt-detail-name"
value={buildResourceLink(resource)}
/>
<Detail
label={t`Description`}
dataCy="prompt-detail-description"
value={details.description}
/>
<Detail
label={t`Type`}
dataCy="prompt-detail-type"
value={toTitleCase(details.unified_job_type || details.type)}
/>
{workflowNode && (
<Detail
label={t`Convergence`}
dataCy="prompt-detail-convergence"
value={workflowNode?.all_parents_must_converge ? t`All` : t`Any`}
/>
)}
<Detail label={t`Timeout`} value={formatTimeout(details?.timeout)} />
<Detail
label={t`Timeout`}
dataCy="prompt-detail-timeout"
value={formatTimeout(details?.timeout)}
/>
{details?.type === 'project' && (
<PromptProjectDetail resource={details} />
)}
@ -153,10 +167,10 @@ function PromptDetail({
rows={4}
value={overrides.extra_vars}
name="extra_vars"
dataCy="prompt-detail-variables"
/>
)}
</DetailList>
{details?.type !== 'system_job_template' &&
hasPromptData(launchConfig) &&
hasOverrides && (
@ -179,12 +193,14 @@ function PromptDetail({
<ChipGroup
numChips={5}
totalChips={overrides.credentials.length}
ouiaId="prompt-credential-chips"
>
{overrides.credentials.map((cred) => (
<CredentialChip
key={cred.id}
credential={cred}
isReadOnly
ouiaId={`credential-${cred.id}-chip`}
/>
))}
</ChipGroup>
@ -220,6 +236,7 @@ function PromptDetail({
value={
<ChipGroup
numChips={5}
ouiaId="prompt-job-tag-chips"
totalChips={
!overrides.job_tags || overrides.job_tags === ''
? 0
@ -228,7 +245,11 @@ function PromptDetail({
>
{overrides.job_tags.length > 0 &&
overrides.job_tags.split(',').map((jobTag) => (
<Chip key={jobTag} isReadOnly>
<Chip
key={jobTag}
isReadOnly
ouiaId={`job-tag-${jobTag}-chip`}
>
{jobTag}
</Chip>
))}
@ -248,10 +269,15 @@ function PromptDetail({
? 0
: overrides.skip_tags.split(',').length
}
ouiaId="prompt-skip-tag-chips"
>
{overrides.skip_tags.length > 0 &&
overrides.skip_tags.split(',').map((skipTag) => (
<Chip key={skipTag} isReadOnly>
<Chip
key={skipTag}
isReadOnly
ouiaId={`skip-tag-${skipTag}-chip`}
>
{skipTag}
</Chip>
))}
@ -268,6 +294,7 @@ function PromptDetail({
{(launchConfig.survey_enabled ||
launchConfig.ask_variables_on_launch) && (
<VariablesDetail
dataCy="prompt-detail-variables"
label={t`Variables`}
rows={4}
value={overrides.extra_vars}

View File

@ -137,6 +137,7 @@ function PromptInventorySourceDetail({ resource }) {
<ChipGroup
numChips={5}
totalChips={source_regions.split(',').length}
ouiaId="prompt-region-chips"
>
{source_regions.split(',').map((region) => (
<Chip key={region} isReadOnly>
@ -155,6 +156,7 @@ function PromptInventorySourceDetail({ resource }) {
<ChipGroup
numChips={5}
totalChips={instance_filters.split(',').length}
ouiaId="prompt-instance-filter-chips"
>
{instance_filters.split(',').map((filter) => (
<Chip key={filter} isReadOnly>
@ -170,7 +172,11 @@ function PromptInventorySourceDetail({ resource }) {
fullWidth
label={t`Only Group By`}
value={
<ChipGroup numChips={5} totalChips={group_by.split(',').length}>
<ChipGroup
numChips={5}
totalChips={group_by.split(',').length}
ouiaId="prompt-only-group-by-chips"
>
{group_by.split(',').map((group) => (
<Chip key={group} isReadOnly>
{group}
@ -185,6 +191,7 @@ function PromptInventorySourceDetail({ resource }) {
)}
{source_vars && (
<VariablesDetail
dataCy="prompt-inventory-source-detail-source-variables"
label={t`Source Variables`}
rows={4}
value={source_vars}

View File

@ -195,6 +195,7 @@ function PromptJobTemplateDetail({ resource }) {
<ChipGroup
numChips={5}
totalChips={summary_fields.credentials.length}
ouiaId="prompt-jt-credential-chips"
>
{summary_fields.credentials.map((cred) => (
<CredentialChip key={cred.id} credential={cred} isReadOnly />
@ -211,6 +212,7 @@ function PromptJobTemplateDetail({ resource }) {
<ChipGroup
numChips={5}
totalChips={summary_fields.labels.results.length}
ouiaId="prompt-jt-label-chips"
>
{summary_fields.labels.results.map((label) => (
<Chip key={label.id} isReadOnly>
@ -226,7 +228,11 @@ function PromptJobTemplateDetail({ resource }) {
fullWidth
label={t`Instance Groups`}
value={
<ChipGroup numChips={5} totalChips={instance_groups.length}>
<ChipGroup
numChips={5}
totalChips={instance_groups.length}
ouiaId="prompt-jt-instance-group-chips"
>
{instance_groups.map((ig) => (
<Chip key={ig.id} isReadOnly>
{ig.name}
@ -241,7 +247,11 @@ function PromptJobTemplateDetail({ resource }) {
fullWidth
label={t`Job Tags`}
value={
<ChipGroup numChips={5} totalChips={job_tags.split(',').length}>
<ChipGroup
numChips={5}
totalChips={job_tags.split(',').length}
ouiaId="prompt-jt-job-tag-chips"
>
{job_tags.split(',').map((jobTag) => (
<Chip key={jobTag} isReadOnly>
{jobTag}
@ -256,7 +266,11 @@ function PromptJobTemplateDetail({ resource }) {
fullWidth
label={t`Skip Tags`}
value={
<ChipGroup numChips={5} totalChips={skip_tags.split(',').length}>
<ChipGroup
numChips={5}
totalChips={skip_tags.split(',').length}
ouiaId="prompt-jt-skip-tag-chips"
>
{skip_tags.split(',').map((skipTag) => (
<Chip key={skipTag} isReadOnly>
{skipTag}
@ -272,6 +286,7 @@ function PromptJobTemplateDetail({ resource }) {
rows={4}
value={extra_vars}
name="extra_vars"
dataCy="prompt-jt-detail-extra-vars"
/>
)}
</>

View File

@ -69,11 +69,13 @@ function PromptProjectDetail({ resource }) {
);
}
const prefixCy = 'prompt-project-detail';
return (
<>
{summary_fields?.organization ? (
<Detail
label={t`Organization`}
dataCy={`${prefixCy}-organization`}
value={
<Link
to={`/organizations/${summary_fields.organization.id}/details`}
@ -92,14 +94,28 @@ function PromptProjectDetail({ resource }) {
/>
<Detail
label={t`Source Control Type`}
dataCy={`${prefixCy}-source-control-type`}
value={scm_type === '' ? t`Manual` : toTitleCase(scm_type)}
/>
<Detail label={t`Source Control URL`} value={scm_url} />
<Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={t`Source Control Refspec`} value={scm_refspec} />
<Detail
label={t`Source Control URL`}
dataCy={`${prefixCy}-source-control-url`}
value={scm_url}
/>
<Detail
label={t`Source Control Branch`}
dataCy={`${prefixCy}-source-control-branch`}
value={scm_branch}
/>
<Detail
label={t`Source Control Refspec`}
dataCy={`${prefixCy}-source-control-refspec`}
value={scm_refspec}
/>
{summary_fields?.credential?.id && (
<Detail
label={t`Source Control Credential`}
dataCy={`${prefixCy}-source-control-credential`}
value={
<CredentialChip
key={resource.summary_fields.credential.id}
@ -109,17 +125,32 @@ function PromptProjectDetail({ resource }) {
}
/>
)}
{optionsList && <Detail label={t`Enabled Options`} value={optionsList} />}
{optionsList && (
<Detail
label={t`Enabled Options`}
dataCy={`${prefixCy}-enabled-options`}
value={optionsList}
/>
)}
<Detail
label={t`Cache Timeout`}
dataCy={`${prefixCy}-cache-timeout`}
value={`${scm_update_cache_timeout} ${t`Seconds`}`}
/>
<Config>
{({ project_base_dir }) => (
<Detail label={t`Project Base Path`} value={project_base_dir} />
<Detail
label={t`Project Base Path`}
dataCy={`${prefixCy}-project-base-path`}
value={project_base_dir}
/>
)}
</Config>
<Detail label={t`Playbook Directory`} value={local_path} />
<Detail
label={t`Playbook Directory`}
dataCy={`${prefixCy}-playbook-directory`}
value={local_path}
/>
</>
);
}

View File

@ -116,6 +116,7 @@ function PromptWFJobTemplateDetail({ resource }) {
<ChipGroup
numChips={5}
totalChips={summary_fields.labels.results.length}
ouiaId="prompt-wf-jt-label-chips"
>
{summary_fields.labels.results.map((label) => (
<Chip key={label.id} isReadOnly>
@ -132,6 +133,7 @@ function PromptWFJobTemplateDetail({ resource }) {
rows={4}
value={extra_vars}
name="extra_vars"
dataCy="prompt-wf-jt-detail-variables"
/>
)}
</>

View File

@ -51,7 +51,10 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete }) {
const [teamRoles, userRoles] = getRoleLists();
return (
<Tr id={`access-item-row-${accessRecord.id}`}>
<Tr
id={`access-item-row-${accessRecord.id}`}
ouiaId={`access-item-row-${accessRecord.id}`}
>
<Td id={`access-record-${accessRecord.id}`} dataLabel={t`Name`}>
{accessRecord.id ? (
<Link to={{ pathname: `/users/${accessRecord.id}/details` }}>
@ -69,7 +72,11 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete }) {
<Detail
label={t`User Roles`}
value={
<ChipGroup numChips={5} totalChips={userRoles.length}>
<ChipGroup
numChips={5}
totalChips={userRoles.length}
ouiaId="user-role-chips"
>
{userRoles.map(renderChip)}
</ChipGroup>
}
@ -79,7 +86,11 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete }) {
<Detail
label={t`Team Roles`}
value={
<ChipGroup numChips={5} totalChips={teamRoles.length}>
<ChipGroup
numChips={5}
totalChips={teamRoles.length}
ouiaId="team-role-chips"
>
{teamRoles.map(renderChip)}
</ChipGroup>
}

View File

@ -29,7 +29,11 @@ function RoutedTabs({ tabsArray }) {
}
return (
<Tabs activeKey={getActiveTabId()} onSelect={handleTabSelect}>
<Tabs
activeKey={getActiveTabId()}
onSelect={handleTabSelect}
ouiaId="routed-tabs"
>
{tabsArray.map((tab) => (
<Tab
aria-label={typeof tab.name === 'string' ? tab.name : null}
@ -38,6 +42,7 @@ function RoutedTabs({ tabsArray }) {
link={tab.link}
title={<TabTitleText>{tab.name}</TabTitleText>}
aria-controls=""
ouiaId={`${tab.name}-tab`}
/>
))}
</Tabs>

View File

@ -330,9 +330,18 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
fullWidth
label={t`Credentials`}
value={
<ChipGroup numChips={5} totalChips={credentials.length}>
<ChipGroup
numChips={5}
totalChips={credentials.length}
ouiaId="schedule-credential-chips"
>
{credentials.map((c) => (
<CredentialChip key={c.id} credential={c} isReadOnly />
<CredentialChip
key={c.id}
credential={c}
isReadOnly
ouiaId={`credential-${c.id}-chip`}
/>
))}
</ChipGroup>
}
@ -346,9 +355,14 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
<ChipGroup
numChips={5}
totalChips={job_tags.split(',').length}
ouiaId="schedule-job-tag-chips"
>
{job_tags.split(',').map((jobTag) => (
<Chip key={jobTag} isReadOnly>
<Chip
key={jobTag}
isReadOnly
ouiaId={`job-tag-${jobTag}-chip`}
>
{jobTag}
</Chip>
))}
@ -364,9 +378,14 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
<ChipGroup
numChips={5}
totalChips={skip_tags.split(',').length}
ouiaId="schedule-skip-tag-chips"
>
{skip_tags.split(',').map((skipTag) => (
<Chip key={skipTag} isReadOnly>
<Chip
key={skipTag}
isReadOnly
ouiaId={`skip-tag-${skipTag}-chip`}
>
{skipTag}
</Chip>
))}
@ -380,6 +399,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
rows={4}
label={t`Variables`}
name="extra_vars"
dataCy="schedule-detail-variables"
/>
)}
</PromptDetailList>

View File

@ -64,7 +64,10 @@ function ScheduleListItem({
const isDisabled = Boolean(isMissingInventory || isMissingSurvey);
return (
<Tr id={`schedule-row-${schedule.id}`}>
<Tr
id={`schedule-row-${schedule.id}`}
ouiaId={`schedule-row-${schedule.id}`}
>
<Td
select={{
rowIndex,

View File

@ -64,6 +64,7 @@ function ScheduleToggle({ schedule, onToggle, className, isDisabled }) {
}
onChange={toggleSchedule}
aria-label={t`Toggle schedule`}
ouiaId={`schedule-${schedule.id}-toggle`}
/>
</Tooltip>
{showError && error && !isLoading && (

View File

@ -249,6 +249,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Sunday`}
id="schedule-days-of-week-sun"
ouiaId="schedule-days-of-week-sun"
name="daysOfWeek"
/>
<Checkbox
@ -259,6 +260,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Monday`}
id="schedule-days-of-week-mon"
ouiaId="schedule-days-of-week-mon"
name="daysOfWeek"
/>
<Checkbox
@ -269,6 +271,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Tuesday`}
id="schedule-days-of-week-tue"
ouiaId="schedule-days-of-week-tue"
name="daysOfWeek"
/>
<Checkbox
@ -279,6 +282,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Wednesday`}
id="schedule-days-of-week-wed"
ouiaId="schedule-days-of-week-wed"
name="daysOfWeek"
/>
<Checkbox
@ -289,6 +293,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Thursday`}
id="schedule-days-of-week-thu"
ouiaId="schedule-days-of-week-thu"
name="daysOfWeek"
/>
<Checkbox
@ -299,6 +304,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Friday`}
id="schedule-days-of-week-fri"
ouiaId="schedule-days-of-week-fri"
name="daysOfWeek"
/>
<Checkbox
@ -309,6 +315,7 @@ const FrequencyDetailSubform = () => {
}}
aria-label={t`Saturday`}
id="schedule-days-of-week-sat"
ouiaId="schedule-days-of-week-sat"
name="daysOfWeek"
/>
</div>
@ -499,6 +506,7 @@ const FrequencyDetailSubform = () => {
event.target.value = 'never';
end.onChange(event);
}}
ouiaId="end-never-radio-button"
/>
<Radio
id="end-after"
@ -510,6 +518,7 @@ const FrequencyDetailSubform = () => {
event.target.value = 'after';
end.onChange(event);
}}
ouiaId="end-after-radio-button"
/>
<Radio
id="end-on-date"
@ -521,6 +530,7 @@ const FrequencyDetailSubform = () => {
event.target.value = 'onDate';
end.onChange(event);
}}
ouiaId="end-on-radio-button"
/>
</FormGroup>
{end?.value === 'after' && (

View File

@ -33,7 +33,7 @@ const ScreenHeader = ({ breadcrumbConfig, streamType }) => {
>
<div>
{!isOnlyOneCrumb && (
<Breadcrumb>
<Breadcrumb ouiaId="breadcrumb-list">
<Route path="/:path">
<Crumb breadcrumbConfig={breadcrumbConfig} />
</Route>
@ -103,7 +103,7 @@ const Crumb = ({ breadcrumbConfig, showDivider }) => {
const crumb = breadcrumbConfig[match.url];
let crumbElement = (
<BreadcrumbItem key={match.url} showDivider={showDivider}>
<BreadcrumbItem key={match.url} showDivider={showDivider} data-cy={crumb}>
<Link to={match.url}>{crumb}</Link>
</BreadcrumbItem>
);
@ -119,7 +119,11 @@ const Crumb = ({ breadcrumbConfig, showDivider }) => {
<>
{crumbElement}
<Route path={`${match.url}/:path`}>
<Crumb breadcrumbConfig={breadcrumbConfig} showDivider />
<Crumb
breadcrumbConfig={breadcrumbConfig}
showDivider
data-cy={crumb}
/>
</Route>
</>
);

View File

@ -109,7 +109,12 @@ function Search({
const searchOptions = columns
.filter(({ key }) => key !== searchKey)
.map(({ key, name }) => (
<SelectOption key={key} value={name} id={`select-option-${key}`}>
<SelectOption
data-cy={`select-option-${key}`}
id={`select-option-${key}`}
key={key}
value={name}
>
{name}
</SelectOption>
));

View File

@ -32,7 +32,11 @@ function SelectedList(props) {
<Split>
<SplitLabelItem>{label}</SplitLabelItem>
<SplitItem>
<ChipGroup numChips={5} totalChips={selected.length}>
<ChipGroup
numChips={5}
totalChips={selected.length}
ouiaId="selected-list-chips"
>
{selected.map((item) =>
renderChip({
item,

View File

@ -92,7 +92,11 @@ function Sort({ columns, qsConfig, onSort }) {
const sortDropdownItems = columns
.filter(({ key }) => key !== sortKey)
.map(({ key, name }) => (
<DropdownItem key={key} component="button">
<DropdownItem
key={key}
component="button"
ouiaId={`${name}-dropdown-item`}
>
{name}
</DropdownItem>
));
@ -115,8 +119,13 @@ function Sort({ columns, qsConfig, onSort }) {
onSelect={handleDropdownSelect}
direction={up}
isOpen={isSortDropdownOpen}
ouiaId="sort-dropdown"
toggle={
<DropdownToggle id="awx-sort" onToggle={handleDropdownToggle}>
<DropdownToggle
id="awx-sort"
onToggle={handleDropdownToggle}
ouiaId="sort-dropdown-toggle"
>
{sortedColumnName}
</DropdownToggle>
}
@ -128,6 +137,7 @@ function Sort({ columns, qsConfig, onSort }) {
variant={ButtonVariant.control}
aria-label={t`Sort`}
onClick={handleSort}
ouiaId="sort-button"
>
<SortIcon />
</Button>

View File

@ -115,7 +115,10 @@ function TemplateListItem({
return (
<>
<Tr id={`template-row-${template.id}`}>
<Tr
id={`template-row-${template.id}`}
ouiaId={`template-row-${template.id}`}
>
<Td
expand={{
rowIndex,
@ -242,7 +245,10 @@ function TemplateListItem({
</ActionItem>
</ActionsTd>
</Tr>
<Tr isExpanded={isExpanded}>
<Tr
isExpanded={isExpanded}
ouiaId={`template-row-${template.id}-expanded`}
>
<Td colSpan={2} />
<Td colSpan={4}>
<ExpandableRowContent>
@ -317,9 +323,15 @@ function TemplateListItem({
<ChipGroup
numChips={5}
totalChips={summaryFields.credentials.length}
ouiaId={`template-${template.id}-credential-chips`}
>
{summaryFields.credentials.map((c) => (
<CredentialChip key={c.id} credential={c} isReadOnly />
<CredentialChip
key={c.id}
credential={c}
isReadOnly
ouiaId={`credential-${c.id}-chip`}
/>
))}
</ChipGroup>
}
@ -334,9 +346,14 @@ function TemplateListItem({
<ChipGroup
numChips={5}
totalChips={summaryFields.labels.results.length}
ouiaId={`template-${template.id}-label-chips`}
>
{summaryFields.labels.results.map((l) => (
<Chip key={l.id} isReadOnly>
<Chip
key={l.id}
isReadOnly
ouiaId={`label-${l.id}-chip`}
>
{l.name}
</Chip>
))}

View File

@ -32,6 +32,7 @@ function WorkflowActionTooltipItem({
return (
<TooltipItem
id={id}
data-cy={id}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}

View File

@ -132,6 +132,7 @@ function ActivityStream() {
isOpen={isTypeDropdownOpen}
isGrouped
noResultsFoundText={t`No results found`}
ouiaId="activity-type-select"
>
<SelectGroup label={t`Views`} key="views">
<SelectOption key="all_activity" value="all">

View File

@ -56,6 +56,7 @@ function ActivityStreamDetailButton({ streamItem, user, description }) {
streamItem?.changes ? JSON.stringify(streamItem.changes) : ''
}
name="changes"
dataCy="activity-stream-detail-changes"
/>
)}
</DetailList>

View File

@ -37,7 +37,7 @@ function ActivityStreamListItem({ streamItem }) {
const description = <ActivityStreamDescription activity={streamItem} />;
return (
<Tr id={streamItem.id} aria-labelledby={labelId}>
<Tr id={streamItem.id} ouiaId={streamItem.id} aria-labelledby={labelId}>
<Td />
<Td dataLabel={t`Time`}>
{streamItem.timestamp ? formatDateString(streamItem.timestamp) : ''}

View File

@ -16,7 +16,7 @@ function ApplicationTokenListItem({
rowIndex,
}) {
return (
<Tr id={`token-row-${token.id}`}>
<Tr id={`token-row-${token.id}`} ouiaId={`token-row-${token.id}`}>
<Td
select={{
rowIndex,

View File

@ -18,7 +18,10 @@ function ApplicationListItem({
}) {
const labelId = `check-action-${application.id}`;
return (
<Tr id={`application-row-${application.id}`}>
<Tr
id={`application-row-${application.id}`}
ouiaId={`application-row-${application.id}`}
>
<Td
select={{
rowIndex,

View File

@ -110,9 +110,14 @@ function CredentialDetail({ credential }) {
fullWidth
label={<span>{label} *</span>}
value={
<ChipGroup numChips={1} totalChips={1}>
<ChipGroup
numChips={1}
totalChips={1}
ouiaId={`credential-${id}-chips`}
>
<CredentialChip
credential={inputSources[id].summary_fields.source_credential}
ouiaId={`credential-${id}-chip`}
isReadOnly
/>
</ChipGroup>

View File

@ -43,7 +43,7 @@ function CredentialListItem({
}, []);
return (
<Tr id={`${credential.id}`}>
<Tr id={`${credential.id}`} ouiaId={`${credential.id}`}>
<Td
select={{
rowIndex,

View File

@ -65,6 +65,7 @@ function CredentialPluginTestAlert({
</>
}
variant={testVariant}
ouiaId="credential-plugin-test-alert"
/>
)}
</AlertGroup>

View File

@ -75,12 +75,14 @@ function CredentialTypeDetails({ credentialType }) {
value={jsonToYaml(JSON.stringify(inputs))}
rows={6}
name="input"
dataCy="credential-type-detail-input"
/>
<VariablesDetail
label={t`Injector configuration`}
value={jsonToYaml(JSON.stringify(injectors))}
rows={6}
name="injector"
dataCy="credential-type-detail-injector"
/>
<UserDateDetail
label={t`Created`}

View File

@ -18,7 +18,10 @@ function CredentialTypeListItem({
const labelId = `check-action-${credentialType.id}`;
return (
<Tr id={`credential-type-row-${credentialType.id}`}>
<Tr
id={`credential-type-row-${credentialType.id}`}
ouiaId={`credential-type-row-${credentialType.id}`}
>
<Td
select={{
rowIndex,

View File

@ -117,11 +117,13 @@ function Dashboard() {
aria-label={t`Tabs`}
activeKey={activeTabId}
onSelect={(key, eventKey) => setActiveTabId(eventKey)}
ouiaId="dashboard-tabs"
>
<Tab
aria-label={t`Job status graph tab`}
eventKey={0}
title={<TabTitleText>{t`Job status`}</TabTitleText>}
ouiaId="job-status-graph-tab"
>
<DashboardGraph />
</Tab>
@ -129,6 +131,7 @@ function Dashboard() {
aria-label={t`Recent Jobs list tab`}
eventKey={1}
title={<TabTitleText>{t`Recent Jobs`}</TabTitleText>}
ouiaId="recent-jobs-list-tab"
>
<div>
{activeTabId === 1 && (
@ -140,6 +143,7 @@ function Dashboard() {
aria-label={t`Recent Templates list tab`}
eventKey={2}
title={<TabTitleText>{t`Recent Templates`}</TabTitleText>}
ouiaId="recent-templates-list-tab"
>
<div>
{activeTabId === 2 && (

View File

@ -104,6 +104,7 @@ function DashboardGraph() {
selections={periodSelection}
isOpen={isPeriodDropdownOpen}
noResultsFoundText={t`No results found`}
ouiaId="dashboard-period-select"
>
<SelectOption key="month" value="month">
{t`Past month`}
@ -130,6 +131,7 @@ function DashboardGraph() {
}}
selections={jobTypeSelection}
isOpen={isJobTypeDropdownOpen}
ouiaId="dashboard-job-type-select"
>
<SelectOption key="all" value="all">
{t`All job types`}

View File

@ -43,7 +43,10 @@ function ExecutionEnvironmentListItem({
}, []);
return (
<Tr id={`ee-row-${executionEnvironment.id}`}>
<Tr
id={`ee-row-${executionEnvironment.id}`}
ouiaId={`ee-row-${executionEnvironment.id}`}
>
<Td
select={{
rowIndex,

View File

@ -5,7 +5,10 @@ import { Tr, Td } from '@patternfly/react-table';
function ExecutionEnvironmentTemplateListItem({ template, detailUrl }) {
return (
<Tr id={`template-row-${template.id}`}>
<Tr
id={`template-row-${template.id}`}
ouiaId={`template-row-${template.id}`}
>
<Td dataLabel={t`Name`}>
<Link to={`${detailUrl}`}>{template.name}</Link>
</Td>

View File

@ -91,6 +91,7 @@ function HostDetail({ host }) {
rows={4}
value={variables}
name="variables"
dataCy="host-detail-variables"
/>
</DetailList>
<CardActionsRow>

View File

@ -46,6 +46,7 @@ function HostFacts({ host }) {
rows="auto"
value={facts}
name="facts"
dataCy="host-facts-detail"
/>
</DetailList>
</CardBody>

View File

@ -16,7 +16,7 @@ function HostGroupItem({ group, inventoryId, isSelected, onSelect, rowIndex }) {
const editUrl = `/inventories/inventory/${inventoryId}/groups/${group.id}/edit`;
return (
<Tr id={`group-row-${group.id}`}>
<Tr id={`group-row-${group.id}`} ouiaId={`group-row-${group.id}`}>
<Td
select={{
rowIndex,

View File

@ -30,7 +30,7 @@ function HostListItem({
return (
<>
<Tr id={`host-row-${host.id}`}>
<Tr id={`host-row-${host.id}`} ouiaId={`host-row-${host.id}`}>
<Td
expand={{
rowIndex,
@ -79,7 +79,7 @@ function HostListItem({
</ActionItem>
</ActionsTd>
</Tr>
<Tr isExpanded={isExpanded}>
<Tr ouiaId={`host-row-${host.id}-expanded`} isExpanded={isExpanded}>
<Td colSpan={2} />
<Td colSpan={4}>
<ExpandableRowContent>

View File

@ -26,6 +26,7 @@ function SmartInventoryButton({ onClick, isDisabled, hasInvalidKeys }) {
isDisabled={isDisabled}
component="button"
onClick={onClick}
ouiaId="smart-inventory-dropdown-item"
>
{t`Smart Inventory`}
</DropdownItem>

View File

@ -82,6 +82,7 @@ function ContainerGroupDetails({ instanceGroup, defaultExecution }) {
}
rows={6}
name="pod_spec_override"
dataCy="container-group-detail-pod-spec-override"
/>
)}
</DetailList>

View File

@ -49,7 +49,7 @@ function InstanceGroupListItem({
}
return (
<Tr id={`ig-row-${instanceGroup.id}`}>
<Tr id={`ig-row-${instanceGroup.id}`} ouiaId={`ig-row-${instanceGroup.id}`}>
<Td
select={{
rowIndex,

View File

@ -110,7 +110,10 @@ function InstanceListItem({
return (
<>
<Tr id={`instance-row-${instance.id}`}>
<Tr
id={`instance-row-${instance.id}`}
ouiaId={`instance-row-${instance.id}`}
>
<Td
expand={{
rowIndex,
@ -186,7 +189,10 @@ function InstanceListItem({
</ActionItem>
</ActionsTd>
</Tr>
<Tr isExpanded={isExpanded}>
<Tr
ouiaId={`instance-row-${instance.id}-expanded`}
isExpanded={isExpanded}
>
<Td colSpan={2} />
<Td colSpan={7}>
<ExpandableRowContent>

View File

@ -83,9 +83,17 @@ function InventoryDetail({ inventory }) {
fullWidth
label={t`Instance Groups`}
value={
<ChipGroup numChips={5} totalChips={instanceGroups.length}>
<ChipGroup
numChips={5}
totalChips={instanceGroups.length}
ouiaId="instance-group-chips"
>
{instanceGroups.map((ig) => (
<Chip key={ig.id} isReadOnly>
<Chip
key={ig.id}
isReadOnly
ouiaId={`instance-group-${ig.id}-chip`}
>
{ig.name}
</Chip>
))}
@ -98,6 +106,7 @@ function InventoryDetail({ inventory }) {
value={inventory.variables}
rows={4}
name="variables"
dataCy="inventory-detail-variables"
/>
<UserDateDetail
label={t`Created`}

View File

@ -38,6 +38,7 @@ function InventoryGroupDetail({ inventoryGroup }) {
value={variables}
rows={4}
name="variables"
dataCy="inventory-group-detail-variables"
/>
<UserDateDetail label={t`Created`} date={created} user={created_by} />
<UserDateDetail

View File

@ -161,6 +161,7 @@ function InventoryGroupHostList() {
onClick={() => setIsModalOpen(true)}
key={addExistingHost}
aria-label={addExistingHost}
ouiaId="add-existing-host-dropdown-item"
>
{addExistingHost}
</DropdownItem>,
@ -169,6 +170,7 @@ function InventoryGroupHostList() {
to={`${addFormUrl}`}
key={addNewHost}
aria-label={addNewHost}
ouiaId="add-new-host-dropdown-item"
>
{addNewHost}
</DropdownItem>,

View File

@ -28,7 +28,11 @@ function InventoryGroupHostListItem({
const labelId = `check-action-${host.id}`;
return (
<Tr id={host.id} arialabelledby={labelId}>
<Tr
id={host.id}
ouiaId={`inventory-group-host-row-${host.id}`}
arialabelledby={labelId}
>
<Td
select={{
rowIndex,

View File

@ -22,7 +22,7 @@ function InventoryGroupItem({
const editUrl = `/inventories/inventory/${inventoryId}/groups/${group.id}/edit`;
return (
<Tr id={`group-row-${group.id}`}>
<Tr id={`group-row-${group.id}`} ouiaId={`group-row-${group.id}`}>
<Td
data-cy={labelId}
select={{

View File

@ -90,6 +90,7 @@ function InventoryHostDetail({ host }) {
rows={4}
value={variables}
name="variables"
dataCy="inventory-host-detail-variables"
/>
</DetailList>
<CardActionsRow>

View File

@ -40,6 +40,7 @@ function InventoryHostFacts({ host }) {
rows="auto"
value={result}
name="facts"
dataCy="inventory-host-facts-detail"
/>
</DetailList>
</CardBody>

View File

@ -21,7 +21,10 @@ function InventoryHostGroupItem({
const editUrl = `/inventories/inventory/${inventoryId}/groups/${group.id}/edit`;
return (
<Tr id={`inventory-host-group-row-${group.id}`}>
<Tr
id={`inventory-host-group-row-${group.id}`}
ouiaId={`inventory-host-group-row-${group.id}`}
>
<Td
data-cy={labelId}
select={{

View File

@ -21,7 +21,7 @@ function InventoryHostItem({
const labelId = `check-action-${host.id}`;
return (
<Tr id={`host-row-${host.id}`}>
<Tr id={`host-row-${host.id}`} ouiaId={`inventory-host-row-${host.id}`}>
<Td
data-cy={labelId}
select={{

View File

@ -72,7 +72,11 @@ function InventoryListItem({
}
return (
<Tr id={inventory.id} aria-labelledby={labelId}>
<Tr
id={inventory.id}
aria-labelledby={labelId}
ouiaId={`inventory-row-${inventory.id}`}
>
<Td
select={{
rowIndex,
@ -142,6 +146,7 @@ function InventoryListItem({
onCopyStart={handleCopyStart}
onCopyFinish={handleCopyFinish}
errorMessage={t`Failed to copy inventory.`}
ouiaId={`${inventory.id}-copy-button`}
/>
</ActionItem>
</ActionsTd>

View File

@ -148,6 +148,7 @@ function InventoryRelatedGroupList() {
key={addExistingGroup}
onClick={() => setIsModalOpen(true)}
aria-label={addExistingGroup}
ouiaId="add-existing-group-dropdown-item"
>
{addExistingGroup}
</DropdownItem>,

View File

@ -23,7 +23,11 @@ function InventoryRelatedGroupListItem({
const labelId = `check-action-${group.id}`;
return (
<Tr id={group.id} aria-labelledby={labelId}>
<Tr
id={group.id}
ouiaId={`group-row-${group.id}`}
aria-labelledby={labelId}
>
<Td
select={{
rowIndex,

View File

@ -255,6 +255,7 @@ function InventorySourceDetail({ inventorySource }) {
rows={4}
value={source_vars}
name="source_vars"
dataCy="inventory-source-detail-variables"
/>
)}
<UserDateDetail date={created} label={t`Created`} user={created_by} />

View File

@ -58,7 +58,7 @@ function InventorySourceListItem({
return (
<>
<Tr id={`source-row-${source.id}`}>
<Tr id={`source-row-${source.id}`} ouiaId={`source-row-${source.id}`}>
<Td
data-cy={`check-action-${source.id}`}
select={{

View File

@ -121,9 +121,17 @@ function SmartInventoryDetail({ inventory }) {
fullWidth
label={t`Instance groups`}
value={
<ChipGroup numChips={5} totalChips={instanceGroups.length}>
<ChipGroup
numChips={5}
totalChips={instanceGroups.length}
ouiaId="instance-group-chips"
>
{instanceGroups.map((ig) => (
<Chip key={ig.id} isReadOnly>
<Chip
key={ig.id}
isReadOnly
ouiaId={`instance-group-${ig.id}-chip`}
>
{ig.name}
</Chip>
))}
@ -136,6 +144,7 @@ function SmartInventoryDetail({ inventory }) {
value={variables}
rows={4}
name="variables"
dataCy="smart-inventory-detail-variables"
/>
<UserDateDetail label={t`Created`} date={created} user={created_by} />
<UserDateDetail

View File

@ -55,6 +55,7 @@ function SmartInventoryHostDetail({ host }) {
rows={4}
value={variables}
name="variables"
dataCy="smart-inventory-host-detail-variables"
/>
</DetailList>
</CardBody>

View File

@ -22,7 +22,7 @@ function SmartInventoryHostListItem({
}));
return (
<Tr id={`host-row-${host.id}`}>
<Tr id={`host-row-${host.id}`} ouiaId={`host-row-${host.id}`}>
<Td
select={{
rowIndex,

View File

@ -63,6 +63,7 @@ const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => {
component="button"
aria-label={t`Delete`}
onClick={() => setIsModalOpen(true)}
ouiaId="group-delete-dropdown-item"
>
{t`Delete`}
</DropdownItem>
@ -72,6 +73,7 @@ const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => {
aria-label={t`Delete`}
onClick={() => setIsModalOpen(true)}
isDisabled={isDisabled || isDeleteLoading}
ouiaId="group-delete-button"
>
{t`Delete`}
</Button>
@ -95,6 +97,7 @@ const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => {
variant="danger"
key="delete"
isDisabled={radioOption === null}
ouiaId="delete-modal-confirm-button"
>
{t`Delete`}
</Button>,
@ -103,6 +106,7 @@ const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => {
onClick={() => setIsModalOpen(false)}
variant="link"
key="cancel"
ouiaId="delete-modal-cancel-button"
>
{t`Cancel`}
</Button>,
@ -126,6 +130,7 @@ const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => {
label={t`Delete All Groups and Hosts`}
name="option"
onChange={() => setRadioOption('delete')}
ouiaId="delete-all-radio-button"
/>
<Radio
css="margin-top: 5px;"
@ -134,6 +139,7 @@ const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => {
label={t`Promote Child Groups and Hosts`}
name="option"
onChange={() => setRadioOption('promote')}
ouiaId="promote-radio-button"
/>
</div>
</AlertModal>

View File

@ -315,11 +315,16 @@ function JobDetail({ job, inventorySourceLabels }) {
dataCy="job-machine-credential"
label={t`Machine Credential`}
value={
<ChipGroup numChips={5} totalChips={1}>
<ChipGroup
numChips={5}
totalChips={1}
ouiaId="job-machine-credential-chips"
>
<CredentialChip
key={credential.id}
credential={credential}
isReadOnly
ouiaId={`job-machine-credential-${credential.id}-chip`}
/>
</ChipGroup>
}
@ -331,9 +336,18 @@ function JobDetail({ job, inventorySourceLabels }) {
fullWidth
label={t`Credentials`}
value={
<ChipGroup numChips={5} totalChips={credentials.length}>
<ChipGroup
numChips={5}
totalChips={credentials.length}
ouiaId="job-credential-chips"
>
{credentials.map((c) => (
<CredentialChip key={c.id} credential={c} isReadOnly />
<CredentialChip
key={c.id}
credential={c}
isReadOnly
ouiaId={`job-credential-${c.id}-chip`}
/>
))}
</ChipGroup>
}
@ -345,9 +359,13 @@ function JobDetail({ job, inventorySourceLabels }) {
fullWidth
label={t`Labels`}
value={
<ChipGroup numChips={5} totalChips={labels.results.length}>
<ChipGroup
numChips={5}
totalChips={labels.results.length}
ouiaId="job-label-chips"
>
{labels.results.map((l) => (
<Chip key={l.id} isReadOnly>
<Chip key={l.id} isReadOnly ouiaId={`job-label-${l.id}-chip`}>
{l.name}
</Chip>
))}
@ -364,9 +382,14 @@ function JobDetail({ job, inventorySourceLabels }) {
<ChipGroup
numChips={5}
totalChips={job.job_tags.split(',').length}
ouiaId="job-tag-chips"
>
{job.job_tags.split(',').map((jobTag) => (
<Chip key={jobTag} isReadOnly>
<Chip
key={jobTag}
isReadOnly
ouiaId={`job-tag-${jobTag}-chip`}
>
{jobTag}
</Chip>
))}
@ -383,9 +406,14 @@ function JobDetail({ job, inventorySourceLabels }) {
<ChipGroup
numChips={5}
totalChips={job.skip_tags.split(',').length}
ouiaId="job-skip-tag-chips"
>
{job.skip_tags.split(',').map((skipTag) => (
<Chip key={skipTag} isReadOnly>
<Chip
key={skipTag}
isReadOnly
ouiaId={`job-skip-tag-${skipTag}-chip`}
>
{skipTag}
</Chip>
))}
@ -418,6 +446,7 @@ function JobDetail({ job, inventorySourceLabels }) {
rows={4}
label={t`Variables`}
name="extra_vars"
dataCy="job-detail-extra-variables"
/>
)}
{job.artifacts && (
@ -429,6 +458,7 @@ function JobDetail({ job, inventorySourceLabels }) {
rows={4}
label={t`Artifacts`}
name="artifacts"
dataCy="job-detail-artifacts"
/>
)}
</DetailList>

View File

@ -99,14 +99,17 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false }) {
title={t`Host Details`}
aria-label={t`Host details modal`}
width="75%"
ouiaId="host-event-modal"
>
<Tabs
aria-label={t`Tabs`}
activeKey={activeTabKey}
onSelect={handleTabClick}
ouiaId="host-event-tabs"
>
<Tab
aria-label={t`Details tab`}
ouiaId="details-tab"
eventKey={0}
title={<TabTitleText>{t`Details`}</TabTitleText>}
>
@ -139,6 +142,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false }) {
eventKey={1}
title={<TabTitleText>{t`JSON`}</TabTitleText>}
aria-label={t`JSON tab`}
ouiaId="json-tab"
>
{activeTabKey === 1 && jsonObj ? (
<CodeEditor
@ -157,6 +161,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false }) {
eventKey={2}
title={<TabTitleText>{t`Standard Out`}</TabTitleText>}
aria-label={t`Standard out tab`}
ouiaId="standard-out-tab"
>
{activeTabKey === 2 && stdOut ? (
<CodeEditor
@ -175,6 +180,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false }) {
eventKey={3}
title={<TabTitleText>{t`Standard Error`}</TabTitleText>}
aria-label={t`Standard error tab`}
ouiaId="standard-error-tab"
>
{activeTabKey === 3 && stdErr ? (
<CodeEditor

View File

@ -140,6 +140,7 @@ function JobOutputSearch({
clearAllFilters={handleRemoveAllSearchTerms}
collapseListedFiltersBreakpoint="lg"
clearFiltersButtonText={t`Clear all filters`}
ouiaId="job-output-toolbar"
>
<SearchToolbarContent>
<ToolbarToggleGroup toggleIcon={<SearchIcon />} breakpoint="lg">

View File

@ -73,7 +73,7 @@ function WorkflowOutputToolbar({ job }) {
);
};
return (
<Toolbar id="workflow-output-toolbar">
<Toolbar id="workflow-output-toolbar" ouiaId="workflow-output-toolbar">
<ToolbarJob>
<StatusIconWithMargin status={job.status} />
<b>{job.name}</b>

View File

@ -152,6 +152,7 @@ function AWXLogin({ alt, isAuthenticated }) {
variant="warning"
isInline
title={t`Your session has expired. Please log in to continue where you left off.`}
ouiaId="session-expired-warning-alert"
/>
) : null}
<Formik

View File

@ -59,9 +59,10 @@ function ManagementJobListItem({
}
};
const rowId = `mgmt-jobs-row-${jobType ? jobType.replace('_', '-') : ''}`;
return (
<>
<Tr id={`mgmt-jobs-row-${jobType ? jobType.replace('_', '-') : ''}`}>
<Tr id={rowId} ouiaId={rowId}>
<Td />
<Td dataLabel={t`Name`}>
<Link to={`${detailsUrl}`}>

View File

@ -181,7 +181,7 @@ function Metrics() {
<PageSection>
<Card>
<CardHeader>
<Toolbar>
<Toolbar ouiaId="metrics-toolbar">
<ToolbarContent>
<ToolbarGroup>
<ToolbarItem>{t`Instance`}</ToolbarItem>

View File

@ -97,7 +97,10 @@ function NotificationTemplateListItem({
return (
<>
<Tr id={`notification-template-row-${template.id}`}>
<Tr
id={`notification-template-row-${template.id}`}
ouiaId={`notification-template-row-${template.id}`}
>
<Td
select={{
rowIndex,

View File

@ -116,10 +116,18 @@ function OrganizationDetail({ organization }) {
fullWidth
label={t`Instance Groups`}
value={
<ChipGroup numChips={5} totalChips={instanceGroups.length}>
<ChipGroup
numChips={5}
totalChips={instanceGroups.length}
ouiaId="instance-group-chips"
>
{instanceGroups.map((ig) => (
<Link to={`${buildLinkURL(ig)}${ig.id}/details`} key={ig.id}>
<Chip key={ig.id} isReadOnly>
<Chip
key={ig.id}
isReadOnly
ouiaId={`instance-group-${ig.id}-chip`}
>
{ig.name}
</Chip>
</Link>
@ -133,7 +141,11 @@ function OrganizationDetail({ organization }) {
fullWidth
label={t`Galaxy Credentials`}
value={
<ChipGroup numChips={5} totalChips={galaxy_credentials.length}>
<ChipGroup
numChips={5}
totalChips={galaxy_credentials.length}
ouiaId="galaxy-credential-chips"
>
{galaxy_credentials.map((credential) => (
<Link
key={credential.id}
@ -143,6 +155,7 @@ function OrganizationDetail({ organization }) {
credential={credential}
key={credential.id}
isReadOnly
ouiaId={`galaxy-credential-${credential.id}-chip`}
/>
</Link>
))}

View File

@ -9,7 +9,10 @@ import { ExecutionEnvironment } from 'types';
function OrganizationExecEnvListItem({ executionEnvironment, detailUrl }) {
return (
<Tr id={`ee-row-${executionEnvironment.id}`}>
<Tr
id={`ee-row-${executionEnvironment.id}`}
ouiaId={`ee-row-${executionEnvironment.id}`}
>
<Td dataLabel={t`Name`}>
<Link to={`${detailUrl}`}>{executionEnvironment.name}</Link>
</Td>

View File

@ -32,7 +32,7 @@ function OrganizationListItem({
organization.custom_virtualenv && !organization.default_environment;
return (
<Tr id={`org-row-${organization.id}`}>
<Tr id={`org-row-${organization.id}`} ouiaId={`org-row-${organization.id}`}>
<Td
select={{
rowIndex,

Some files were not shown because too many files have changed in this diff Show More