Skip to content

Commit

Permalink
Merge pull request #1 from empear-analytics/Taking-care-of-tests-with…
Browse files Browse the repository at this point in the history
…out-a-result

Sending a different message when test results can't be found
  • Loading branch information
ulrikawiss authored Mar 30, 2023
2 parents 32f950a + b13301a commit 870e965
Show file tree
Hide file tree
Showing 12 changed files with 9,308 additions and 546 deletions.
21 changes: 21 additions & 0 deletions .github/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Run Tests

on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:

jobs:
run-tests:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '16.14.0'
- run: npm ci --no-progress
- run: npm run test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,7 @@ typings/
# TernJS port file
.tern-port
.DS_Store

# IDE
.idea/
.vscode/
16 changes: 0 additions & 16 deletions .vscode/launch.json

This file was deleted.

17 changes: 17 additions & 0 deletions app/results-parser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import ResultsParser from './results-parser';

test('existing file is parsed OK', async () => {
const result = new ResultsParser('results.xml');
await result.parse();
expect(result.failedTests).toBe(1);
})

test('non-existing file throws ENOENT', async () => {
const result = new ResultsParser('foo.xml');
try {
await result.parse();
} catch (e) {
expect(e.code).toEqual('ENOENT');
}
})

161 changes: 161 additions & 0 deletions app/results.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<testsuites id="" name="" tests="8" failures="1" skipped="1" errors="0" time="195.091">
<testsuite name="cloud/test-4f.spec.ts" timestamp="1655667311825" hostname="" tests="1" failures="1" skipped="0" time="57.449" errors="0">
<testcase name="4 factors dashboard Check 4 factors @dashboard on @cloud" classname="[staging] › cloud/test-4f.spec.ts:11:5 › 4 factors dashboard › Check 4 factors @dashboard on @cloud" time="57.449">
<failure message="test-4f.spec.ts:11:5 Check 4 factors @dashboard on @cloud" type="FAILURE">
[staging] › cloud/test-4f.spec.ts:11:5 › 4 factors dashboard › Check 4 factors @dashboard on @cloud

Error: expect(received).toBeVisible()
Call log:
- expect.toBeVisible with timeout 5000ms
- waiting for selector "[data-automation-id='hotspot-code-health-div']"


15 | const analysisResultsPage = await projectsPage.clickOnProjectTitle(projectName);
16 | let newDashboardPage = await analysisResultsPage.load4f();
> 17 | await newDashboardPage.verifyVisibilityOfHotspotCodeHealth();
| ^
18 | let hotspotsPage = await newDashboardPage.clickOnViewHotspotsLink();
19 | await hotspotsPage.verifyHotspotsTab();
20 | await page.goBack();

at CodeHealthPage.verifyVisibilityOfHotspotCodeHealth (/Users/emir/Codebase/codescene/testing/ui-tests-playwright/pages/common-pages/analysis-results-pages/new-dashboard-page/code-health-page.ts:57:60)
at /Users/emir/Codebase/codescene/testing/ui-tests-playwright/tests/cloud/test-4f.spec.ts:17:30

Error: expect(received).toBeVisible()
Call log:
- expect.toBeVisible with timeout 5000ms
- waiting for selector "[data-automation-id='view-hotspots-in-hotspot-code-health']"


15 | const analysisResultsPage = await projectsPage.clickOnProjectTitle(projectName);
16 | let newDashboardPage = await analysisResultsPage.load4f();
> 17 | await newDashboardPage.verifyVisibilityOfHotspotCodeHealth();
| ^
18 | let hotspotsPage = await newDashboardPage.clickOnViewHotspotsLink();
19 | await hotspotsPage.verifyHotspotsTab();
20 | await page.goBack();

at CodeHealthPage.verifyVisibilityOfHotspotCodeHealth (/Users/emir/Codebase/codescene/testing/ui-tests-playwright/pages/common-pages/analysis-results-pages/new-dashboard-page/code-health-page.ts:58:50)
at /Users/emir/Codebase/codescene/testing/ui-tests-playwright/tests/cloud/test-4f.spec.ts:17:7

locator.click: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for selector "[data-automation-id='view-hotspots-in-hotspot-code-health']"
============================================================

16 | let newDashboardPage = await analysisResultsPage.load4f();
17 | await newDashboardPage.verifyVisibilityOfHotspotCodeHealth();
> 18 | let hotspotsPage = await newDashboardPage.clickOnViewHotspotsLink();
| ^
19 | await hotspotsPage.verifyHotspotsTab();
20 | await page.goBack();
21 | await newDashboardPage.verifyVisibilityOfAverageCodeHealth();

at CodeHealthPage.clickOnViewHotspotsLink (/Users/emir/Codebase/codescene/testing/ui-tests-playwright/pages/common-pages/analysis-results-pages/new-dashboard-page/code-health-page.ts:89:37)
at /Users/emir/Codebase/codescene/testing/ui-tests-playwright/tests/cloud/test-4f.spec.ts:18:49

attachment #1: video (video/webm) --------------------------------------------------------------
test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/video.webm
------------------------------------------------------------------------------------------------

attachment #2: trace (application/zip) ---------------------------------------------------------
test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/trace.zip
Usage:

npx playwright show-trace test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/trace.zip

------------------------------------------------------------------------------------------------

attachment #3: screenshot (image/png) ----------------------------------------------------------
test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/test-failed-1.png
------------------------------------------------------------------------------------------------

</failure>
<system-out>

[[ATTACHMENT|../test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-4f-4-factors-dashboard-Check-4-factors-dashboard-on-cloud-staging/test-failed-1.png]]

</system-out>
</testcase>
</testsuite>
<testsuite name="cloud/test-login.spec.ts" timestamp="1655667311825" hostname="" tests="3" failures="0" skipped="0" time="104.71" errors="0">
<testcase name="Login feature Login with github on @cloud" classname="[staging] › cloud/test-login.spec.ts:10:5 › Login feature › Login with github on @cloud" time="34.088">
<system-out>

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-github-on-cloud-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-github-on-cloud-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-github-on-cloud-staging/test-finished-1.png]]

</system-out>
</testcase>
<testcase name="Login feature Login with bitbucket on @cloud" classname="[staging] › cloud/test-login.spec.ts:10:5 › Login feature › Login with bitbucket on @cloud" time="33.26">
<system-out>

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-bitbucket-on-cloud-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-bitbucket-on-cloud-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-bitbucket-on-cloud-staging/test-finished-1.png]]

</system-out>
</testcase>
<testcase name="Login feature Login with azure on @cloud" classname="[staging] › cloud/test-login.spec.ts:10:5 › Login feature › Login with azure on @cloud" time="37.362">
<system-out>

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-azure-on-cloud-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-azure-on-cloud-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-login-Login-feature-Login-with-azure-on-cloud-staging/test-finished-1.png]]

</system-out>
</testcase>
</testsuite>
<testsuite name="cloud/test-pr-integration.spec.ts" timestamp="1655667311825" hostname="" tests="3" failures="0" skipped="0" time="500.244" errors="0">
<testcase name="PR integration feature Test PR integration with github on @cloud @prIntegration" classname="[staging] › cloud/test-pr-integration.spec.ts:13:5 › PR integration feature › Test PR integration with github on @cloud @prIntegration" time="148.814">
<system-out>

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-eff46--integration-with-github-on-cloud-prIntegration-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-eff46--integration-with-github-on-cloud-prIntegration-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-eff46--integration-with-github-on-cloud-prIntegration-staging/test-finished-1.png]]

</system-out>
</testcase>
<testcase name="PR integration feature Test PR integration with bitbucket on @cloud @prIntegration" classname="[staging] › cloud/test-pr-integration.spec.ts:13:5 › PR integration feature › Test PR integration with bitbucket on @cloud @prIntegration" time="156.852">
<system-out>

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-31950-tegration-with-bitbucket-on-cloud-prIntegration-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-31950-tegration-with-bitbucket-on-cloud-prIntegration-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-31950-tegration-with-bitbucket-on-cloud-prIntegration-staging/test-finished-1.png]]

</system-out>
</testcase>
<testcase name="PR integration feature Test PR integration with azure on @cloud @prIntegration" classname="[staging] › cloud/test-pr-integration.spec.ts:13:5 › PR integration feature › Test PR integration with azure on @cloud @prIntegration" time="194.578">
<system-out>

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-1ac6b-R-integration-with-azure-on-cloud-prIntegration-staging/video.webm]]

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-1ac6b-R-integration-with-azure-on-cloud-prIntegration-staging/trace.zip]]

[[ATTACHMENT|../test-results/cloud-test-pr-integration-PR-integration-featu-1ac6b-R-integration-with-azure-on-cloud-prIntegration-staging/test-finished-1.png]]

</system-out>
</testcase>
</testsuite>
<testsuite name="cloud/test-project-architecture.spec.ts" timestamp="1655667311825" hostname="" tests="1" failures="0" skipped="1" time="0" errors="0">
<testcase name="Architectural components Generate architectural components on @cloud" classname="[staging] › cloud/test-project-architecture.spec.ts:15:8 › Architectural components › Generate architectural components on @cloud" time="0">
<skipped>
</skipped>
</testcase>
</testsuite>
</testsuites>
20 changes: 20 additions & 0 deletions app/slack-message.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ResultsParser from './results-parser';
import SlackMessage from './slack-message';
import ActionInfo from './action-info';

jest.mock('./action-info')

test('blocks created OK for OK results', async () => {
const result = new ResultsParser('results.xml');
await result.parse();
const blocks = new SlackMessage(undefined).getBlocks(result, new ActionInfo());
expect(blocks).toContain(":large_green_circle");
})

test('blocks created OK for unknown results', async () => {
const blocks = new SlackMessage(new ResultsParser('foo.xml')).getUnknownBlocks(new ActionInfo());
expect(blocks).toContain(":Question: *UNKNOWN RESULT:*");
})



57 changes: 53 additions & 4 deletions app/slack-message.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ts-check
import { IncomingWebhook } from '@slack/webhook';
import {IncomingWebhook} from '@slack/webhook';
import ActionInfo from './action-info';
import ResultsParser from './results-parser';

Expand All @@ -15,6 +15,12 @@ export default class SlackMessage {
await webhook.send({ text: `${actionInfo.workflowName} - ${this.testResults.failedTests > 0 ? "Failed": "Passed"}`, blocks: JSON.parse(blocks) });
}

async sendUnknownResult(slackWebhookUrl: string, actionInfo: ActionInfo): Promise<void> {
const webhook = new IncomingWebhook(slackWebhookUrl);
const blocks = this.getUnknownBlocks(actionInfo);
await webhook.send({ text: `${actionInfo.workflowName} - "Unknown result"}`, blocks: JSON.parse(blocks) });
}

private getFailedTestsSections(failed, failedTestsList: string[]): string {
const template = (testName: string, isFailed: boolean) => `{
"type": "section",
Expand Down Expand Up @@ -54,7 +60,7 @@ export default class SlackMessage {
const failed = failedTests > 0;
const failedTestsSections = this.getFailedTestsSections(failed, failedTestsList);
const overralTestsSection = this.getOverralTestsSection(passedTests, skippedTests, failedTests);
const nesta = `
return `
[
{
"type": "context",
Expand Down Expand Up @@ -100,7 +106,50 @@ export default class SlackMessage {
]
}
]
`
return nesta;
`;
}

getUnknownBlocks(actionInfo: ActionInfo): string {
return `
[
{
"type": "context",
"elements": [
{
"type": "plain_text",
"text": "Action: ${actionInfo.workflowName}",
"emoji": true
}
]
},
{
"type": "divider"
},
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":Question: *UNKNOWN RESULT:* No test result was found, check the Action for more info."
}
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Go to Action",
"emoji": true
},
"value": "action_go",
"url": "${actionInfo.runUrl}"
}
]
}
]
`;
}

}
6 changes: 6 additions & 0 deletions babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};
8 changes: 6 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ let testOutputFile = core.getInput("directory-path") ? core.getInput("directory-
(async () => {
const workspacePath = process.env.GITHUB_WORKSPACE;
const result = new ResultsParser(workspacePath + '/' + testOutputFile);
await result.parse();
await new SlackMessage(result).send(slackWebhookUrl, new ActionInfo());
try {
await result.parse();
await new SlackMessage(result).send(slackWebhookUrl, new ActionInfo());
} catch (e) {
await new SlackMessage(result).sendUnknownResult(slackWebhookUrl, new ActionInfo());
}
})();
Loading

0 comments on commit 870e965

Please sign in to comment.