1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-25 08:19:40 +02:00

chore(data-cy): require data-cy attributes [EE-6880] (#11453)
Some checks are pending
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
ci / build_images (map[arch:arm platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:s390x platform:linux version:]) (push) Waiting to run
ci / build_manifests (push) Blocked by required conditions
/ triage (push) Waiting to run
Lint / Run linters (push) Waiting to run
Test / test-client (push) Waiting to run
Test / test-server (map[arch:amd64 platform:linux]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
Test / test-server (map[arch:arm64 platform:linux]) (push) Waiting to run

This commit is contained in:
Ali 2024-04-11 12:11:38 +12:00 committed by GitHub
parent 3cad13388c
commit d38085a560
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
538 changed files with 2571 additions and 595 deletions

View file

@ -84,6 +84,7 @@ export function BaseForm({
setFieldValue('name', name);
}}
placeholder="e.g. myContainer"
data-cy="container-name-input"
/>
</FormControl>
@ -108,6 +109,7 @@ export function BaseForm({
setFieldValue('alwaysPull', alwaysPull)
}
labelClass="col-sm-3 col-lg-2"
data-cy="always-pull-switch"
/>
</div>
</div>
@ -121,6 +123,7 @@ export function BaseForm({
<div className="col-sm-12">
<SwitchField
label="Create a container webhook"
data-cy="container-webhook-switch"
tooltip="Create a webhook (or callback URI) to automate the recreate this container. Sending a POST request to this callback URI (without requiring any authentication) will pull the most up-to-date version of the associated image and recreate this container."
checked={values.enableWebhook}
onChange={(enableWebhook) =>
@ -140,6 +143,7 @@ export function BaseForm({
<div className="col-sm-12">
<SwitchField
label="Publish all exposed ports to random host ports"
data-cy="publish-all-ports-switch"
tooltip="When enabled, Portainer will let Docker automatically map a random port on the host to each one defined in the image Dockerfile."
checked={values.publishAllPorts}
onChange={(publishAllPorts) =>
@ -179,6 +183,7 @@ export function BaseForm({
<div className="col-sm-12">
<SwitchField
label="Auto remove"
data-cy="container-auto-remove-switch"
tooltip="When enabled, Portainer will automatically remove the container when it exits. This is useful when you want to use the container only once."
checked={values.autoRemove}
onChange={(autoRemove) => setFieldValue('autoRemove', autoRemove)}
@ -191,6 +196,7 @@ export function BaseForm({
<div className="col-sm-12">
<LoadingButton
loadingText="Deployment in progress..."
data-cy="deploy-container-button"
isLoading={isLoading}
disabled={!isValid}
>

View file

@ -50,6 +50,7 @@ export function PortsMappingField({
disabled={disabled}
readOnly={readOnly}
tooltip="When a range of ports on the host and a single port on the container is specified, Docker will randomly choose a single available port in the defined range and forward that to the container port."
data-cy="docker-containers-ports-mapping"
/>
{typeof errors === 'string' && (
<div className="form-group col-md-12">
@ -73,6 +74,7 @@ function Item({
<div className="flex items-center gap-2">
<InputLabeled
size="small"
data-cy={`hostPort-${index}`}
disabled={disabled}
readOnly={readOnly}
value={item.hostPort}
@ -97,6 +99,7 @@ function Item({
placeholder="e.g. 80"
className="w-1/2"
id={`containerPort-${index}`}
data-cy={`containerPort-${index}`}
/>
<ButtonSelector<Protocol>

View file

@ -19,6 +19,7 @@ export function CapabilitiesTab({
<div key={cap.key} className="w-1/3 text-center">
<SwitchField
labelClass="col-sm-6"
data-cy="docker-container-capability-switch"
tooltip={cap.description}
checked={values.includes(cap.key)}
label={cap.key}

View file

@ -61,6 +61,7 @@ export function CommandsTab({
value={values.workingDir}
onChange={(e) => setFieldValue('workingDir', e.target.value)}
placeholder="e.g. /myapp"
data-cy="working-dir-input"
/>
</FormControl>
<FormControl
@ -73,6 +74,7 @@ export function CommandsTab({
value={values.user}
onChange={(e) => setFieldValue('user', e.target.value)}
placeholder="e.g. nginx"
data-cy="user-input"
/>
</FormControl>
</div>

View file

@ -2,6 +2,8 @@ import { ReactNode } from 'react';
import { mixed } from 'yup';
import { ContainerConfig } from 'docker-types/generated/1.41';
import { AutomationTestingProps } from '@/types';
import { FormControl } from '@@/form-components/FormControl';
const consoleSettingTypes = ['tty', 'interactive', 'both', 'none'] as const;
@ -28,6 +30,7 @@ export function ConsoleSettings({
</>
}
selected={value}
data-cy="container-console-interactive-tty"
/>
<Item
value="interactive"
@ -38,6 +41,7 @@ export function ConsoleSettings({
</>
}
selected={value}
data-cy="container-console-interactive"
/>
<Item
value="tty"
@ -48,12 +52,14 @@ export function ConsoleSettings({
</>
}
selected={value}
data-cy="container-console-tty"
/>
<Item
value="none"
onChange={handleChange}
label={<>None</>}
selected={value}
data-cy="container-console-none"
/>
</FormControl>
);
@ -68,16 +74,18 @@ function Item({
selected,
onChange,
label,
'data-cy': dataCy,
}: {
value: ConsoleSetting;
selected: ConsoleSetting;
onChange(value: ConsoleSetting): void;
label: ReactNode;
}) {
} & AutomationTestingProps) {
return (
<label className="radio-inline !m-0 w-1/2">
<input
type="radio"
data-cy={dataCy}
name="container_console"
value={value}
checked={value === selected}

View file

@ -52,6 +52,7 @@ export function LoggerConfig({
value={value.type}
onChange={(type) => onChange({ ...value, type: type || '' })}
options={pluginOptions}
data-cy="docker-logging-driver-selector"
/>
</FormControl>
@ -82,6 +83,7 @@ export function LoggerConfig({
itemBuilder={() => ({ option: '', value: '' })}
disabled={isDisabled}
errors={errors?.options}
data-cy="docker-logging-options"
/>
</FormSection>
);
@ -95,6 +97,7 @@ function Item({
item: { option, value },
onChange,
error,
index,
}: ItemProps<{ option: string; value: string }>) {
return (
<div>
@ -105,6 +108,7 @@ function Item({
value={option}
onChange={(e) => handleChange({ option: e.target.value })}
placeholder="e.g. FOO"
data-cy={`docker-logging-option_${index}`}
/>
</InputGroup>
<InputGroup className="w-1/2">
@ -113,6 +117,7 @@ function Item({
value={value}
onChange={(e) => handleChange({ value: e.target.value })}
placeholder="e.g bar"
data-cy={`docker-logging-value_${index}`}
/>
</InputGroup>
</div>

View file

@ -21,6 +21,7 @@ export function OverridableInput({
<InputGroup.ButtonWrapper>
<Button
color="light"
data-cy={`docker-container-default-${id}`}
size="medium"
className={clsx('!ml-0', { active: !override })}
onClick={() => onChange(null)}
@ -29,6 +30,7 @@ export function OverridableInput({
</Button>
<Button
color="light"
data-cy={`docker-container-override-${id}`}
size="medium"
className={clsx({ active: override })}
onClick={() => onChange('')}
@ -38,6 +40,7 @@ export function OverridableInput({
</InputGroup.ButtonWrapper>
<InputGroup.Input
disabled={!override}
data-cy={`docker-container-input-${id}`}
value={value || ''}
onChange={(e) => onChange(e.target.value)}
id={id}

View file

@ -4,7 +4,7 @@ import { ItemProps } from '@@/form-components/InputList';
import { Label } from './types';
export function Item({ item, onChange, error }: ItemProps<Label>) {
export function Item({ item, onChange, error, index }: ItemProps<Label>) {
return (
<div className="w-full">
<div className="flex w-full gap-4">
@ -12,6 +12,7 @@ export function Item({ item, onChange, error }: ItemProps<Label>) {
<InputGroup.Addon>name</InputGroup.Addon>
<InputGroup.Input
value={item.name}
data-cy={`label-name_${index}`}
onChange={(e) => onChange({ ...item, name: e.target.value })}
placeholder="e.g. com.example.foo"
/>
@ -20,6 +21,7 @@ export function Item({ item, onChange, error }: ItemProps<Label>) {
<InputGroup.Addon>value</InputGroup.Addon>
<InputGroup.Input
value={item.value}
data-cy={`label-value${index}`}
onChange={(e) => onChange({ ...item, value: e.target.value })}
placeholder="e.g. bar"
/>

View file

@ -21,6 +21,7 @@ export function LabelsTab({
value={values}
item={Item}
itemBuilder={() => ({ name: '', value: '' })}
data-cy="docker-container-labels"
/>
);

View file

@ -31,6 +31,7 @@ export function ContainerSelector({
onChange={onChange}
options={containersQuery.data || []}
isLoading={containersQuery.isLoading}
data-cy="docker-container-selector"
/>
);
}

View file

@ -44,6 +44,7 @@ export function NetworkTab({
value={values.hostname}
onChange={(e) => setFieldValue('hostname', e.target.value)}
placeholder="e.g. web01"
data-cy="docker-container-hostname-input"
/>
</FormControl>
@ -52,6 +53,7 @@ export function NetworkTab({
value={values.domain}
onChange={(e) => setFieldValue('domain', e.target.value)}
placeholder="e.g. example.com"
data-cy="docker-container-domain-input"
/>
</FormControl>
@ -60,6 +62,7 @@ export function NetworkTab({
value={values.macAddress}
onChange={(e) => setFieldValue('macAddress', e.target.value)}
placeholder="e.g. 12-34-56-78-9a-bc"
data-cy="docker-container-mac-address-input"
/>
</FormControl>
@ -68,6 +71,7 @@ export function NetworkTab({
value={values.ipv4Address}
onChange={(e) => setFieldValue('ipv4Address', e.target.value)}
placeholder="e.g. 172.20.0.7"
data-cy="docker-container-ipv4-address-input"
/>
</FormControl>
@ -76,6 +80,7 @@ export function NetworkTab({
value={values.ipv6Address}
onChange={(e) => setFieldValue('ipv6Address', e.target.value)}
placeholder="e.g. a:b:c:d::1234"
data-cy="docker-container-ipv6-address-input"
/>
</FormControl>
@ -84,6 +89,7 @@ export function NetworkTab({
value={values.primaryDns}
onChange={(e) => setFieldValue('primaryDns', e.target.value)}
placeholder="e.g. 1.1.1.1, 2606:4700:4700::1111"
data-cy="docker-container-primary-dns-input"
/>
</FormControl>
@ -92,6 +98,7 @@ export function NetworkTab({
value={values.secondaryDns}
onChange={(e) => setFieldValue('secondaryDns', e.target.value)}
placeholder="e.g. 1.0.0.1, 2606:4700:4700::1001"
data-cy="docker-container-secondary-dns-input"
/>
</FormControl>
@ -104,6 +111,7 @@ export function NetworkTab({
errors={errors?.hostsFileEntries}
item={HostsFileEntryItem}
itemBuilder={() => ''}
data-cy="docker-container-hosts-file-entries"
/>
</div>
);
@ -115,6 +123,7 @@ function HostsFileEntryItem({
disabled,
error,
readOnly,
index,
}: ItemProps<string>) {
return (
<div>
@ -125,6 +134,7 @@ function HostsFileEntryItem({
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
readOnly={readOnly}
data-cy={`docker-container-hosts-file-entry_${index}`}
/>
</InputGroup>

View file

@ -31,16 +31,18 @@ export function DevicesField({
label="Devices"
errors={errors}
itemBuilder={() => ({ pathOnHost: '', pathInContainer: '' })}
data-cy="docker-container-devices"
/>
);
}
function Item({ item, onChange, error }: ItemProps<Device>) {
function Item({ item, onChange, error, index }: ItemProps<Device>) {
return (
<div className="w-full">
<div className="flex w-full gap-4">
<InputLabeled
value={item.pathOnHost}
data-cy={`device-path-on-host_${index}`}
onChange={(e) => onChange({ ...item, pathOnHost: e.target.value })}
label="host"
placeholder="e.g. /dev/tty0"
@ -49,6 +51,7 @@ function Item({ item, onChange, error }: ItemProps<Device>) {
/>
<InputLabeled
value={item.pathInContainer}
data-cy={`device-path-on-container_${index}`}
onChange={(e) =>
onChange({ ...item, pathInContainer: e.target.value })
}

View file

@ -73,6 +73,7 @@ export function EditResourcesForm({
<div className="col-sm-12 flex items-center gap-4">
<LoadingButton
isLoading={updateMutation.isLoading}
data-cy="update-limits-button"
disabled={isImageInvalid || !dirty}
loadingText="Update in progress..."
type="button"

View file

@ -136,6 +136,7 @@ export function GpuFieldset({
onChange={toggleEnableGpu}
className="ml-2"
disabled={!enableGpuManagement}
data-cy="docker-containers-gpu-enabled-switch"
/>
</div>
{enableGpuManagement && values.enabled && (
@ -150,6 +151,7 @@ export function GpuFieldset({
onChange={onChangeSelectedGpus}
options={options}
components={{ MultiValueRemove }}
data-cy="docker-containers-gpu-select"
/>
</div>
)}
@ -170,6 +172,7 @@ export function GpuFieldset({
options={NvidiaCapabilitiesOptions}
components={{ Option }}
onChange={onChangeSelectedCaps}
data-cy="docker-containers-gpu-capabilities-select"
/>
</div>
</div>

View file

@ -69,6 +69,7 @@ export function ResourceFieldset({
min={0}
max={maxCpu}
step={0.1}
dataCy="k8sNamespaceCreate-resourceCpu"
/>
</FormControl>
</FormSection>

View file

@ -99,6 +99,7 @@ export function ResourcesTab({
setFieldValue('sharedMemorySize', e.target.valueAsNumber)
}
className="w-32"
data-cy="shared-memory-size"
/>
<div className="small text-muted">
Size of /dev/shm (<b>MB</b>)

View file

@ -30,6 +30,7 @@ export function RuntimeSection({
<div className="col-sm-12">
<SwitchField
labelClass="col-sm-2"
data-cy="docker-privileged-switch"
label="Privileged mode"
checked={values.privileged}
onChange={(privileged) => handleChange({ privileged })}
@ -43,6 +44,7 @@ export function RuntimeSection({
<div className="col-sm-12">
<SwitchField
labelClass="col-sm-2"
data-cy="docker-init-switch"
label="Init"
checked={values.init}
onChange={(init) => handleChange({ init })}

View file

@ -26,6 +26,7 @@ export function RuntimeSelector({
options={infoQuery.data || []}
isLoading={infoQuery.isLoading}
disabled={infoQuery.isLoading}
data-cy="docker-runtime-selector"
/>
);
}

View file

@ -30,11 +30,12 @@ export function SysctlsField({
label="Sysctls"
errors={errors}
itemBuilder={() => ({ name: '', value: '' })}
data-cy="docker-container-sysctls"
/>
);
}
function Item({ item, onChange, error }: ItemProps<Sysctls>) {
function Item({ item, onChange, error, index }: ItemProps<Sysctls>) {
return (
<div className="w-full">
<div className="flex w-full gap-4">
@ -45,6 +46,7 @@ function Item({ item, onChange, error }: ItemProps<Sysctls>) {
placeholder="e.g. FOO"
className="w-1/2"
size="small"
data-cy={`docker-container-sysctl-name_${index}`}
/>
<InputLabeled
value={item.value}
@ -53,6 +55,7 @@ function Item({ item, onChange, error }: ItemProps<Sysctls>) {
placeholder="e.g. bar"
className="w-1/2"
size="small"
data-cy={`docker-container-sysctl-value_${index}`}
/>
</div>
{error && <FormError>{Object.values(error)[0]}</FormError>}

View file

@ -31,6 +31,7 @@ export function Item({
size="small"
className="flex-1"
id={`container-path-${index}`}
data-cy={`container-path_${index}`}
/>
{allowBindMounts && (
@ -73,6 +74,7 @@ export function Item({
value={volume.name}
onChange={(e) => setValue({ name: e.target.value })}
id={`host-path-${index}`}
data-cy={`host-path_${index}`}
/>
)}

View file

@ -40,6 +40,7 @@ export function VolumeSelector({
value={selectedValue}
onChange={(vol) => onChange(vol?.Name)}
inputId={inputId}
data-cy="docker-containers-volume-selector"
/>
);
}

View file

@ -31,6 +31,7 @@ export function VolumesTab({
name: '',
readOnly: false,
})}
data-cy="docker-container-volumes"
/>
</InputContext.Provider>
);

View file

@ -29,6 +29,7 @@ function ConfirmRecreationModal({ onSubmit, cannotPullImage }: Props) {
</p>
<SwitchField
name="pullLatest"
data-cy="recreate-pull-latest-switch"
label="Re-pull image"
checked={pullLatest}
onChange={setPullLatest}
@ -44,10 +45,18 @@ function ConfirmRecreationModal({ onSubmit, cannotPullImage }: Props) {
)}
</Modal.Body>
<Modal.Footer>
<Button onClick={() => onSubmit()} color="default">
<Button
onClick={() => onSubmit()}
color="default"
data-cy="cancel-recreate"
>
Cancel
</Button>
<Button onClick={() => onSubmit({ pullLatest })} color="danger">
<Button
onClick={() => onSubmit({ pullLatest })}
color="danger"
data-cy="confirm-recreate"
>
Recreate
</Button>
</Modal.Footer>

View file

@ -55,6 +55,7 @@ export function ConnectNetworkForm({
</div>
<LoadingButton
loadingText="Joining network..."
data-cy="connect-network-button"
isLoading={connectMutation.isLoading}
>
Join Network

View file

@ -62,6 +62,7 @@ export function ContainerNetworksDatatable({
table: 'container-networks',
containerId: container.Id,
})}
data-cy="container-networks-datatable"
/>
);
}

View file

@ -29,6 +29,7 @@ function Cell({
<Authorized authorizations="DockerNetworkDisconnect">
<LoadingButton
color="dangerlight"
data-cy="disconnect-network-button"
isLoading={disconnectMutation.isLoading}
loadingText="Leaving network..."
type="button"

View file

@ -8,7 +8,11 @@ import { actions } from './actions';
export const columns = [
buildExpandColumn<TableNetwork>(),
{
...buildNameColumn<TableNetwork>('name', 'docker.networks.network'),
...buildNameColumn<TableNetwork>(
'name',
'docker.networks.network',
'docker-networks-name'
),
header: 'Network',
},
columnHelper.accessor((item) => item.IPAddress || '-', {

View file

@ -25,7 +25,7 @@ export function HealthStatus({ health }: Props) {
<TableContainer>
<TableTitle label="Container health" icon={Server} />
<DetailsTable>
<DetailsTable dataCy="health-status-table">
<DetailsTable.Row label="Status">
<div className="vertical-center">
<Icon

View file

@ -70,6 +70,7 @@ export function ContainersDatatable({
isLoading={containersQuery.isLoading}
isRowSelectable={(row) => !row.original.IsPortainer}
initialTableState={getColumnVisibilityState(tableState.hiddenColumns)}
data-cy="docker-containers-datatable"
renderTableSettings={(tableInstance) => (
<>
<ColumnVisibilityMenu<DockerContainer>

View file

@ -82,6 +82,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerStart">
<Button
color="light"
data-cy="start-docker-container-button"
onClick={() => onStartClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasStoppedItemsSelected}
icon={Play}
@ -93,6 +94,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerStop">
<Button
color="light"
data-cy="stop-docker-container-button"
onClick={() => onStopClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasRunningItemsSelected}
icon={Square}
@ -104,6 +106,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerKill">
<Button
color="light"
data-cy="kill-docker-container-button"
onClick={() => onKillClick(selectedItems)}
disabled={selectedItemCount === 0 || hasStoppedItemsSelected}
icon={Slash}
@ -115,6 +118,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerRestart">
<Button
color="light"
data-cy="restart-docker-container-button"
onClick={() => onRestartClick(selectedItems)}
disabled={selectedItemCount === 0}
icon={RefreshCw}
@ -126,6 +130,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerPause">
<Button
color="light"
data-cy="pause-docker-container-button"
onClick={() => onPauseClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasRunningItemsSelected}
icon={Pause}
@ -137,6 +142,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerUnpause">
<Button
color="light"
data-cy="resume-docker-container-button"
onClick={() => onResumeClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasPausedItemsSelected}
icon={Play}
@ -148,6 +154,7 @@ export function ContainersDatatableActions({
<Authorized authorizations="DockerContainerDelete">
<Button
color="dangerlight"
data-cy="remove-docker-container-button"
onClick={() => onRemoveClick(selectedItems)}
disabled={selectedItemCount === 0}
icon={Trash2}
@ -159,7 +166,9 @@ export function ContainersDatatableActions({
{isAddActionVisible && (
<div className="space-left">
<Authorized authorizations="DockerContainerCreate">
<AddButton>Add container</AddButton>
<AddButton data-cy="add-docker-container-button">
Add container
</AddButton>
</Authorized>
</div>
)}

View file

@ -16,7 +16,8 @@ export function ContainersDatatableSettings({
return (
<>
<Checkbox
id="settings-container-truncate-nae"
id="settings-container-truncate-name"
data-cy="settings-container-truncate-name"
label="Truncate container name"
checked={settings.truncateContainerName > 0}
onChange={() =>

View file

@ -36,6 +36,7 @@ function LogsDisabledInfoPanel() {
<Link
to="docker.containers.new"
params={{ from: containerId, nodeName }}
data-cy="redeploy-container-link"
>
redeploy your container
</Link>{' '}

View file

@ -53,6 +53,7 @@ export function ProcessesDatatable({
disableSelect
isLoading={!dataset}
emptyContentLabel="No processes found."
data-cy="docker-container-stats-processes-datatable"
/>
);
}

View file

@ -9,6 +9,7 @@ export async function confirmContainerDeletion(title: string) {
{
confirmButton: buildConfirmButton('Remove', 'danger'),
modalType: ModalType.Destructive,
'data-cy': 'confirm-container-delete-button',
}
);

View file

@ -45,6 +45,7 @@ export function ContainerQuickActions({
to="docker.containers.container.logs"
params={{ id: containerId, nodeName }}
title="Logs"
data-cy={`container-logs-${containerId}`}
>
<Icon icon={FileText} className="space-right" />
</Link>
@ -57,6 +58,7 @@ export function ContainerQuickActions({
to="docker.containers.container.inspect"
params={{ id: containerId, nodeName }}
title="Inspect"
data-cy={`container-inspect-${containerId}`}
>
<Icon icon={Info} className="space-right" />
</Link>
@ -69,6 +71,7 @@ export function ContainerQuickActions({
to="docker.containers.container.stats"
params={{ id: containerId, nodeName }}
title="Stats"
data-cy={`container-stats-${containerId}`}
>
<Icon icon={BarChart} className="space-right" />
</Link>
@ -81,6 +84,7 @@ export function ContainerQuickActions({
to="docker.containers.container.exec"
params={{ id: containerId, nodeName }}
title="Exec Console"
data-cy={`container-exec-${containerId}`}
>
<Icon icon={Terminal} className="space-right" />
</Link>
@ -93,6 +97,7 @@ export function ContainerQuickActions({
to="docker.containers.container.attach"
params={{ id: containerId, nodeName }}
title="Attach Console"
data-cy={`container-attach-${containerId}`}
>
<Icon icon={Paperclip} className="space-right" />
</Link>

View file

@ -44,6 +44,7 @@ export function NetworkSelector({
isLoading={networksQuery.isLoading}
bindToBody
placeholder="Select a network"
data-cy="docker-network-selector"
/>
);
}