Skip to content

Commit

Permalink
Merge pull request #1112 from w3c/development
Browse files Browse the repository at this point in the history
Issues addressed:
* #1105, addresses w3c/aria-at#1070
* #1053, addresses w3c/aria-practices#2971
* #1097, addresses #977
* #1095, addresses #991
* #1093, addresses #934
* #1000, addresses #818
* #1089, addresses #992
* #1067, addresses #993
* #1056, addresses w3c/wai-aria-practices#212

---------

Co-authored-by: alflennik <alflennik@users.noreply.github.com>
Co-authored-by: Paul Clue <67766160+Paul-Clue@users.noreply.github.com>
Co-authored-by: Mx Corey Frang <corey@bocoup.com>
Co-authored-by: Mx. Corey Frang <gnarf37@gmail.com>
Co-authored-by: Erika Miguel <erika@bocoup.com>
Co-authored-by: Mike Pennisi <mike@mikepennisi.com>
  • Loading branch information
7 people authored May 28, 2024
2 parents 7b992b6 + 2b88c5f commit 9f5ada4
Show file tree
Hide file tree
Showing 93 changed files with 2,183 additions and 7,015 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Deploy to production (aria-at.w3.org)

on:
push:
branches:
- main

jobs:
deploy-production:
runs-on: ubuntu-latest

steps:
- name: Install SSH key for deploying
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
known_hosts: ${{ secrets.DEPLOY_KNOWN_HOSTS_PRODUCTION }}
config: ${{ secrets.DEPLOY_SSH_CONFIG }}
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install ansible and deploy to production
run: |
python -m pip install --user ansible-core==2.11.1
cd deploy
echo ${{ secrets.ANSIBLE_VAULT_PASSWORD }} > ansible-vault-password.txt
ansible-vault view --vault-password-file ansible-vault-password.txt files/jwt-signing-key.pem.enc > ../jwt-signing-key.pem
ansible-galaxy collection install ansible.posix
ansible-playbook provision.yml -e ansible_python_interpreter=/usr/bin/python3 --inventory inventory/production.yml
2 changes: 1 addition & 1 deletion .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy to staging
name: Deploy to staging (aria-at-staging.w3.org)

on:
push:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,5 @@ server/migrations/test_plan_target_id.csv

# Private Key files (installed by deploy)
jwt-signing-key.pem

client/resources
12 changes: 10 additions & 2 deletions client/components/AddTestToQueueWithConfirmation/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,16 @@ function AddTestToQueueWithConfirmation({

AddTestToQueueWithConfirmation.propTypes = {
testPlanVersion: PropTypes.object,
browser: PropTypes.object,
at: PropTypes.object,
browser: PropTypes.shape({
id: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
}),
at: PropTypes.shape({
id: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
}),
buttonRef: PropTypes.object,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
Expand Down
152 changes: 60 additions & 92 deletions client/components/BotRunTestStatusList/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import {
COLLECTION_JOB_STATUS_BY_TEST_PLAN_RUN_ID_QUERY,
TEST_PLAN_RUNS_TEST_RESULTS_QUERY
} from './queries';
import { useLazyQuery, useQuery } from '@apollo/client';
import { TEST_PLAN_RUNS_TEST_RESULTS_QUERY } from './queries';
import { useQuery } from '@apollo/client';
import styled from '@emotion/styled';
import ReportStatusDot from '../common/ReportStatusDot';
import { isBot } from '../../utils/automation';

const BotRunTestStatusUnorderedList = styled.ul`
list-style-type: none;
Expand Down Expand Up @@ -35,121 +31,93 @@ const BotRunTestStatusUnorderedList = styled.ul`
const testCountString = (count, status) =>
`${count} Test${count === 1 ? '' : 's'} ${status}`;

const BotRunTestStatusList = ({ testPlanReportId, runnableTestsLength }) => {
const pollInterval = 2000;

const BotRunTestStatusList = ({ testPlanReportId }) => {
const {
data: testPlanRunsQueryResult,
startPolling,
stopPolling
} = useQuery(TEST_PLAN_RUNS_TEST_RESULTS_QUERY, {
variables: { testPlanReportId },
fetchPolicy: 'cache-and-network',
pollInterval: 2000
pollInterval
});

const [getCollectionJobStatus, { data: collectionJobStatusQueryResult }] =
useLazyQuery(COLLECTION_JOB_STATUS_BY_TEST_PLAN_RUN_ID_QUERY, {
fetchPolicy: 'cache-and-network'
});

const [collectedData, setCollectedData] = useState([]);
const requestedTestRunIds = useRef(new Set());

const botTestPlanRuns = useMemo(() => {
if (!testPlanRunsQueryResult?.testPlanRuns) {
return [];
}
return testPlanRunsQueryResult.testPlanRuns.filter(testPlanRun =>
isBot(testPlanRun.tester)
);
}, [testPlanRunsQueryResult?.testPlanRuns]);

useEffect(() => {
const ids = botTestPlanRuns.map(run => run.id);
for (const id of ids) {
if (!requestedTestRunIds.current.has(id)) {
requestedTestRunIds.current.add(id);
getCollectionJobStatus({
variables: { testPlanRunId: id }
});
}
}
}, [botTestPlanRuns]);

useEffect(() => {
if (collectionJobStatusQueryResult?.collectionJobByTestPlanRunId) {
const { status } =
collectionJobStatusQueryResult.collectionJobByTestPlanRunId;
setCollectedData(prev => [...prev, status]);
}
}, [collectionJobStatusQueryResult?.collectionJobByTestPlanRunId]);

const [numTestsCompleted, numTestsQueued, numTestsCancelled] =
useMemo(() => {
const res = [0, 0, 0];
if (
botTestPlanRuns &&
botTestPlanRuns.length &&
collectedData.length === botTestPlanRuns.length
) {
for (let i = 0; i < botTestPlanRuns.length; i++) {
const status = collectedData[i];
res[0] += botTestPlanRuns[i].testResults.length;
switch (status) {
case 'COMPLETED':
case 'RUNNING':
case 'QUEUED':
res[1] +=
runnableTestsLength -
botTestPlanRuns[i].testResults.length;
break;
case 'CANCELLED':
res[2] +=
runnableTestsLength -
botTestPlanRuns[i].testResults.length;
break;
default:
break;
const { COMPLETED, ERROR, RUNNING, CANCELLED, QUEUED } = useMemo(() => {
const counter = {
COMPLETED: 0,
ERROR: 0,
RUNNING: 0,
CANCELLED: 0,
QUEUED: 0
};
let anyPossibleUpdates = false;
if (testPlanRunsQueryResult?.testPlanRuns) {
for (const {
collectionJob
} of testPlanRunsQueryResult.testPlanRuns) {
if (collectionJob?.testStatus) {
for (const { status } of collectionJob.testStatus) {
counter[status]++;
if (status === 'QUEUED' || status === 'RUNNING') {
anyPossibleUpdates = true;
}
}
}
if (
res[0] + res[2] ===
runnableTestsLength * botTestPlanRuns.length
) {
stopPolling();
}
}
return res;
}, [testPlanRunsQueryResult, collectedData, stopPolling, startPolling]);
// it's possible that we got incomplete data on first fetch and
// stopped the polling, so restart the polling if we detect any
// possible future updates, otherwise stop.
if (anyPossibleUpdates) {
startPolling(pollInterval);
} else {
stopPolling();
}
}
return counter;
}, [testPlanRunsQueryResult, stopPolling, startPolling]);

if (
!botTestPlanRuns ||
botTestPlanRuns.length === 0 ||
!collectedData ||
!(collectedData.length === botTestPlanRuns.length)
!testPlanRunsQueryResult ||
testPlanRunsQueryResult.testPlanRuns.length === 0
) {
return null;
}
return (
<BotRunTestStatusUnorderedList className="text-secondary fs-6">
{RUNNING > 0 && (
<li className="m-2">
<ReportStatusDot className="tests-running" />
{testCountString(RUNNING, 'Running')}
</li>
)}
{ERROR > 0 && (
<li className="m-2">
<ReportStatusDot className="tests-error" />
{testCountString(ERROR, 'Error')}
</li>
)}
<li className="m-2">
<ReportStatusDot className="tests-complete" />
{testCountString(numTestsCompleted, 'Completed')}
{testCountString(COMPLETED, 'Completed')}
</li>
<li className="m-2">
<ReportStatusDot className="tests-queued" />
{testCountString(numTestsQueued, 'Queued')}
</li>
<li className="m-2">
<ReportStatusDot className="tests-cancelled" />
{testCountString(numTestsCancelled, 'Cancelled')}
{testCountString(QUEUED, 'Queued')}
</li>
{CANCELLED > 0 && (
<li className="m-2">
<ReportStatusDot className="tests-cancelled" />
{testCountString(CANCELLED, 'Cancelled')}
</li>
)}
</BotRunTestStatusUnorderedList>
);
};

BotRunTestStatusList.propTypes = {
testPlanReportId: PropTypes.string.isRequired,
runnableTestsLength: PropTypes.number.isRequired
testPlanReportId: PropTypes.string.isRequired
};

export default BotRunTestStatusList;
15 changes: 6 additions & 9 deletions client/components/BotRunTestStatusList/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@ export const TEST_PLAN_RUNS_TEST_RESULTS_QUERY = gql`
}
}
}
}
}
`;

export const COLLECTION_JOB_STATUS_BY_TEST_PLAN_RUN_ID_QUERY = gql`
query CollectionJobStatusByTestPlanRunId($testPlanRunId: ID!) {
collectionJobByTestPlanRunId(testPlanRunId: $testPlanRunId) {
id
status
collectionJob {
status
testStatus {
status
}
}
}
}
`;
8 changes: 8 additions & 0 deletions client/components/DataManagement/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ export const DATA_MANAGEMENT_PAGE_QUERY = gql`
}
ats {
id
key
name
browsers {
id
key
name
}
atVersions {
Expand Down Expand Up @@ -66,10 +68,12 @@ export const DATA_MANAGEMENT_PAGE_QUERY = gql`
markedFinalAt
at {
id
key
name
}
browser {
id
key
name
}
issues {
Expand Down Expand Up @@ -135,10 +139,12 @@ export const UPDATE_TEST_PLAN_VERSION_PHASE = gql`
id
at {
id
key
name
}
browser {
id
key
name
}
issues {
Expand Down Expand Up @@ -182,10 +188,12 @@ export const UPDATE_TEST_PLAN_VERSION_RECOMMENDED_TARGET_DATE = gql`
id
at {
id
key
name
}
browser {
id
key
name
}
issues {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ StopRunningCollectionButton.propTypes = {
'CANCELLED',
'COMPLETED',
'ERROR'
])
]).isRequired
}),
onClick: PropTypes.func
};
Expand Down
3 changes: 1 addition & 2 deletions client/components/ManageBotRunDialog/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from './queries';
import DeleteButton from '../common/DeleteButton';
import BotRunTestStatusList from '../BotRunTestStatusList';
import { isBot } from '../../utils/automation';

import './ManageBotRunDialog.css';
import MarkBotRunFinishedButton from './MarkBotRunFinishedButton';
Expand Down Expand Up @@ -59,7 +58,7 @@ const ManageBotRunDialog = ({
() =>
testers.filter(
t =>
!isBot(t) &&
!t.isBot &&
!testPlanReportAssignedTestersQuery?.testPlanReport.draftTestPlanRuns.some(
d => d.tester.id === t.id
)
Expand Down
15 changes: 14 additions & 1 deletion client/components/ManageTestQueue/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,20 @@ const ManageTestQueue = ({
};

ManageTestQueue.propTypes = {
ats: PropTypes.array,
ats: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
browsers: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
})
).isRequired
})
).isRequired,
testPlanVersions: PropTypes.array,
triggerUpdate: PropTypes.func
};
Expand Down
Loading

0 comments on commit 9f5ada4

Please sign in to comment.