diff --git a/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.test.tsx b/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.test.tsx index 2bfc9d0959..32c2f2f8fb 100644 --- a/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.test.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.test.tsx @@ -108,12 +108,37 @@ describe('CircleCI', () => { return { mockMetricMutationVariables, user } } - describe('step one', () => { + describe('output coverage step', () => { it('renders header', async () => { setup({}) render(, { wrapper }) - const header = await screen.findByRole('heading', { name: /Step 1/ }) + const header = await screen.findByText( + /Step \d: Output a Coverage report file in your CI/ + ) + expect(header).toBeInTheDocument() + }) + + it('renders body', async () => { + setup({}) + render(, { wrapper }) + + const body = await screen.findByText(/Select your language below/) + expect(body).toBeInTheDocument() + + const jest = await screen.findByText(/Jest/) + expect(jest).toBeInTheDocument() + }) + }) + + describe('token step', () => { + it('renders header', async () => { + setup({}) + render(, { wrapper }) + + const header = await screen.findByRole('heading', { + name: /Step \d: add repository token to environment variables/, + }) expect(header).toBeInTheDocument() }) @@ -204,13 +229,15 @@ describe('CircleCI', () => { }) }) - describe('step two', () => { + describe('orb yaml step', () => { beforeEach(() => setup({})) it('renders header', async () => { render(, { wrapper }) - const header = await screen.findByRole('heading', { name: /Step 2/ }) + const header = await screen.findByRole('heading', { + name: /Step \d: add Codecov orb to CircleCI/, + }) expect(header).toBeInTheDocument() const CircleCIJSWorkflowLink = await screen.findByRole('link', { @@ -252,8 +279,18 @@ describe('CircleCI', () => { }) }) - describe('step three', () => { + describe('merge step', () => { beforeEach(() => setup({})) + + it('renders header', async () => { + render(, { wrapper }) + + const header = await screen.findByText( + /Step \d: merge to main or your preferred feature branch/ + ) + expect(header).toBeInTheDocument() + }) + it('renders body', async () => { render(, { wrapper }) @@ -299,6 +336,7 @@ describe('CircleCI', () => { describe('user copies text', () => { it('stores codecov metric', async () => { + // will be removing this stuff soon, backend for this doesn't exist anymore const { mockMetricMutationVariables } = setup({}) const user = userEvent.setup() render(, { wrapper }) @@ -306,13 +344,13 @@ describe('CircleCI', () => { const copyCommands = await screen.findAllByTestId( 'clipboard-code-snippet' ) - expect(copyCommands.length).toEqual(3) + expect(copyCommands.length).toEqual(5) await user.click(copyCommands[1] as HTMLElement) await user.click(copyCommands[2] as HTMLElement) await waitFor(() => - expect(mockMetricMutationVariables).toHaveBeenCalledTimes(2) + expect(mockMetricMutationVariables).toHaveBeenCalledTimes(1) ) }) }) diff --git a/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx b/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx index f00c0dd694..e71d397713 100644 --- a/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react' import { useParams } from 'react-router-dom' import envVarScreenshot from 'assets/onboarding/env_variable_screenshot.png' @@ -17,6 +18,11 @@ import { ExpandableSection } from 'ui/ExpandableSection' import ExampleBlurb from '../ExampleBlurb' import LearnMoreBlurb from '../LearnMoreBlurb' +import OutputCoverageStep from '../OutputCoverageStep/OutputCoverageStep' +import { + Framework, + UseFrameworkInstructions, +} from '../UseFrameworkInstructions' const orbsString = `orbs: codecov: codecov/codecov@5 @@ -49,15 +55,28 @@ function CircleCI() { const uploadToken = orgUploadToken ?? data?.repository?.uploadToken ?? '' const tokenCopy = orgUploadToken ? 'global' : 'repository' + const [framework, setFramework] = useState('Jest') + const frameworkInstructions = UseFrameworkInstructions({ + orgUploadToken, + owner, + repo, + }) + return (
- + - - + +
@@ -66,20 +85,20 @@ function CircleCI() { export default CircleCI -interface Step1Props { +interface TokenStepProps { tokenCopy: string uploadToken: string providerName: string } -function Step1({ tokenCopy, uploadToken, providerName }: Step1Props) { +function TokenStep({ tokenCopy, uploadToken, providerName }: TokenStepProps) { const { mutate: storeEventMetric } = useStoreCodecovEventMetric() const { owner } = useParams() return ( - Step 1: add {tokenCopy} token to environment variables + Step 2: add {tokenCopy} token to environment variables @@ -133,18 +152,18 @@ function Step1({ tokenCopy, uploadToken, providerName }: Step1Props) { ) } -interface Step2Props { +interface OrbYAMLStepProps { defaultBranch: string } -function Step2({ defaultBranch }: Step2Props) { +function OrbYAMLStep({ defaultBranch }: OrbYAMLStepProps) { const { mutate: storeEventMetric } = useStoreCodecovEventMetric() const { owner } = useParams() return ( - Step 2: add Codecov orb to CircleCI{' '} + Step 3: add Codecov orb to CircleCI{' '} - Step 3: merge to main or your preferred feature branch + Step 4: merge to main or your preferred feature branch diff --git a/src/pages/RepoPage/CoverageOnboarding/GitHubActions/GitHubActions.tsx b/src/pages/RepoPage/CoverageOnboarding/GitHubActions/GitHubActions.tsx index 5a47ac4608..8bf7e1c3c6 100644 --- a/src/pages/RepoPage/CoverageOnboarding/GitHubActions/GitHubActions.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/GitHubActions/GitHubActions.tsx @@ -10,12 +10,16 @@ import A from 'ui/A' import { Card } from 'ui/Card' import MergeStep from './MergeStep' -import OutputCoverageStep from './OutputCoverageStep' import TokenStep from './TokenStep' -import { Framework } from './types' import WorkflowYMLStep from './WorkflowYMLStep' import LearnMoreBlurb from '../LearnMoreBlurb' +import OutputCoverageStep from '../OutputCoverageStep/OutputCoverageStep' +import { + Framework, + UseFrameworkInstructions, +} from '../UseFrameworkInstructions' + interface URLParams { provider: Provider owner: string @@ -60,161 +64,12 @@ function GitHubActions() { } const [framework, setFramework] = useState('Jest') + const frameworkInstructions = UseFrameworkInstructions({ + orgUploadToken, + owner, + repo, + }) - const frameworkInstructions = { - Jest: { - install: 'npm install --save-dev jest', - run: 'npx jest --coverage', - workflow: `name: Run tests and upload coverage - -on: - push - -jobs: - test: - name: Run tests and collect coverage - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Node - uses: actions/setup-node@v4 - - - name: Install dependencies - run: npm install - - - name: Run tests - run: npx jest --coverage - - - name: Upload results to Codecov - uses: codecov/codecov-action@v5 - with: - token: \${{ secrets.CODECOV_TOKEN }}${ - orgUploadToken - ? ` - slug: ${owner}/${repo}` - : '' - } -`, - }, - Vitest: { - install: 'npm install --save-dev vitest @vitest/coverage-v8', - run: 'npx vitest run --coverage', - workflow: `name: Run tests and upload coverage - -on: - push - -jobs: - test: - name: Run tests and collect coverage - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Node - uses: actions/setup-node@v4 - - - name: Install dependencies - run: npm install - - - name: Run tests - run: npx vitest run --coverage - - - name: Upload results to Codecov - uses: codecov/codecov-action@v5 - with: - token: \${{ secrets.CODECOV_TOKEN }}${ - orgUploadToken - ? ` - slug: ${owner}/${repo}` - : '' - } -`, - }, - Pytest: { - install: 'pip install pytest pytest-cov', - run: 'pytest --cov --cov-report=xml', - workflow: `name: Run tests and upload coverage - -on: - push - -jobs: - test: - name: Run tests and collect coverage - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v4 - - - name: Install dependencies - run: pip install pytest pytest-cov - - - name: Run tests - run: pytest --cov --cov-report=xml - - - name: Upload results to Codecov - uses: codecov/codecov-action@v5 - with: - token: \${{ secrets.CODECOV_TOKEN }}${ - orgUploadToken - ? ` - slug: ${owner}/${repo}` - : '' - } -`, - }, - Go: { - install: undefined, - run: 'go test -coverprofile=coverage.txt', - workflow: `name: Run tests and upload coverage - -on: - push - -jobs: - test: - name: Run tests and collect coverage - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v5 - - - name: Install dependencies - run: go mod download - - - name: Run tests - run: go test -coverprofile=coverage.txt - - - name: Upload results to Codecov - uses: codecov/codecov-action@v5 - with: - token: \${{ secrets.CODECOV_TOKEN }}${ - orgUploadToken - ? ` - slug: ${owner}/${repo}` - : '' - } -`, - }, - } return (
storeEventMetric({ owner, @@ -98,7 +98,7 @@ function WorkflowYMLStep({ }) } > - {frameworkInstructions[framework].workflow} + {frameworkInstructions[framework].githubActionsWorkflow}

{ return { user } } - describe('step one', () => { + describe('output coverage step', () => { it('renders header', async () => { setup({}) render(, { wrapper }) - const header = await screen.findByText(/Step 1/) + const header = await screen.findByText( + /Step \d: Output a Coverage report file in your CI/ + ) + expect(header).toBeInTheDocument() + }) + + it('renders body', async () => { + setup({}) + render(, { wrapper }) + + const body = await screen.findByText(/Select your language below/) + expect(body).toBeInTheDocument() + + const jest = await screen.findByText(/Jest/) + expect(jest).toBeInTheDocument() + }) + }) + + describe('token step', () => { + it('renders header', async () => { + setup({}) + render(, { wrapper }) + + const header = await screen.findByText( + /Step \d: add repository token as a secret to your CI Provider/ + ) expect(header).toBeInTheDocument() }) @@ -151,12 +176,12 @@ describe('OtherCI', () => { }) }) - describe('step two', () => { + describe('install step', () => { beforeEach(() => setup({})) it('renders header', async () => { render(, { wrapper }) - const header = await screen.findByText(/Step 2/) + const header = await screen.findByText(/Step \d: add the/) expect(header).toBeInTheDocument() const headerLink = await screen.findByRole('link', { @@ -177,12 +202,14 @@ describe('OtherCI', () => { }) }) - describe('step three', () => { + describe('upload step', () => { it('renders header', async () => { setup({}) render(, { wrapper }) - const header = await screen.findByText(/Step 3/) + const header = await screen.findByText( + /Step \d: upload coverage to Codecov via the CLI after your tests have run/ + ) expect(header).toBeInTheDocument() }) @@ -231,8 +258,17 @@ describe('OtherCI', () => { }) }) - describe('step four', () => { + describe('merge step', () => { beforeEach(() => setup({})) + it('renders header', async () => { + render(, { wrapper }) + + const header = await screen.findByText( + /Step \d: merge to main or your preferred feature branch/ + ) + expect(header).toBeInTheDocument() + }) + it('renders body', async () => { render(, { wrapper }) diff --git a/src/pages/RepoPage/CoverageOnboarding/OtherCI/OtherCI.tsx b/src/pages/RepoPage/CoverageOnboarding/OtherCI/OtherCI.tsx index f2820b49c1..3504b7d24c 100644 --- a/src/pages/RepoPage/CoverageOnboarding/OtherCI/OtherCI.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/OtherCI/OtherCI.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react' import { useParams } from 'react-router-dom' import config from 'config' @@ -13,6 +14,11 @@ import { InstructionBox } from './TerminalInstructions' import ExampleBlurb from '../ExampleBlurb' import LearnMoreBlurb from '../LearnMoreBlurb' +import OutputCoverageStep from '../OutputCoverageStep/OutputCoverageStep' +import { + Framework, + UseFrameworkInstructions, +} from '../UseFrameworkInstructions' interface URLParams { provider: string @@ -40,12 +46,25 @@ function OtherCI() { orgUploadToken ? ` -r ${owner}/${repo}` : '' }` + const [framework, setFramework] = useState('Jest') + const frameworkInstruction = UseFrameworkInstructions({ + orgUploadToken, + owner, + repo, + }) + return (

@@ -54,17 +73,17 @@ function OtherCI() { export default OtherCI -interface Step1Props { +interface TokenStepProps { tokenCopy: string uploadToken: string } -function Step1({ tokenCopy, uploadToken }: Step1Props) { +function TokenStep({ tokenCopy, uploadToken }: TokenStepProps) { return ( - Step 1: add {tokenCopy} token as a secret to your CI Provider + Step 2: add {tokenCopy} token as a secret to your CI Provider @@ -81,12 +100,12 @@ function Step1({ tokenCopy, uploadToken }: Step1Props) { ) } -function Step2() { +function InstallStep() { return ( - Step 2: add the{' '} + Step 3: add the{' '} - Step 3: upload coverage to Codecov via the CLI after your tests have + Step 4: upload coverage to Codecov via the CLI after your tests have run @@ -126,12 +145,12 @@ function Step3({ uploadCommand }: Step3Props) { ) } -function Step4() { +function MergeStep() { return ( - Step 4: merge to main or your preferred feature branch + Step 5: merge to main or your preferred feature branch diff --git a/src/pages/RepoPage/CoverageOnboarding/GitHubActions/OutputCoverageStep.test.tsx b/src/pages/RepoPage/CoverageOnboarding/OutputCoverageStep/OutputCoverageStep.test.tsx similarity index 96% rename from src/pages/RepoPage/CoverageOnboarding/GitHubActions/OutputCoverageStep.test.tsx rename to src/pages/RepoPage/CoverageOnboarding/OutputCoverageStep/OutputCoverageStep.test.tsx index 23db3782be..5a6775e174 100644 --- a/src/pages/RepoPage/CoverageOnboarding/GitHubActions/OutputCoverageStep.test.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/OutputCoverageStep/OutputCoverageStep.test.tsx @@ -12,6 +12,8 @@ import { ThemeContextProvider } from 'shared/ThemeContext' import OutputCoverageStep from './OutputCoverageStep' +import { Framework, FrameworkInstructions } from '../UseFrameworkInstructions' + vi.mock('config') const server = setupServer() @@ -69,27 +71,27 @@ describe('OutputCoverageStep', () => { } } - const framework = 'Jest' - const frameworkInstructions = { + const framework: Framework = 'Jest' + const frameworkInstructions: FrameworkInstructions = { Jest: { install: 'npm install --save-dev jest', run: 'npx jest --coverage', - workflow: undefined, + githubActionsWorkflow: '', }, Vitest: { install: '', run: '', - workflow: undefined, + githubActionsWorkflow: '', }, Pytest: { install: '', run: '', - workflow: undefined, + githubActionsWorkflow: '', }, Go: { install: undefined, run: 'go test -coverprofile=coverage.txt', - workflow: undefined, + githubActionsWorkflow: '', }, } const setFramework = vi.fn() diff --git a/src/pages/RepoPage/CoverageOnboarding/GitHubActions/OutputCoverageStep.tsx b/src/pages/RepoPage/CoverageOnboarding/OutputCoverageStep/OutputCoverageStep.tsx similarity index 97% rename from src/pages/RepoPage/CoverageOnboarding/GitHubActions/OutputCoverageStep.tsx rename to src/pages/RepoPage/CoverageOnboarding/OutputCoverageStep/OutputCoverageStep.tsx index 9ae72e7c6d..4637d8f56c 100644 --- a/src/pages/RepoPage/CoverageOnboarding/GitHubActions/OutputCoverageStep.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/OutputCoverageStep/OutputCoverageStep.tsx @@ -7,7 +7,7 @@ import { Card } from 'ui/Card' import { CodeSnippet } from 'ui/CodeSnippet' import Select from 'ui/Select' -import { Framework, FrameworkInstructions } from './types' +import { Framework, FrameworkInstructions } from '../UseFrameworkInstructions' interface OutputCoverageStepProps { framework: Framework diff --git a/src/pages/RepoPage/CoverageOnboarding/UseFrameworkInstructions.tsx b/src/pages/RepoPage/CoverageOnboarding/UseFrameworkInstructions.tsx new file mode 100644 index 0000000000..7d3278ba0c --- /dev/null +++ b/src/pages/RepoPage/CoverageOnboarding/UseFrameworkInstructions.tsx @@ -0,0 +1,174 @@ +import { useMemo } from 'react' + +export type Framework = 'Jest' | 'Vitest' | 'Pytest' | 'Go' +export type FrameworkInstructions = ReturnType + +interface UseFrameworkInstructionsArgs { + orgUploadToken?: string | null + owner: string + repo: string +} + +export function UseFrameworkInstructions({ + orgUploadToken, + owner, + repo, +}: UseFrameworkInstructionsArgs) { + return useMemo( + () => ({ + Jest: { + install: 'npm install --save-dev jest', + run: 'npx jest --coverage', + githubActionsWorkflow: `name: Run tests and upload coverage + +on: + push + +jobs: + test: + name: Run tests and collect coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Node + uses: actions/setup-node@v4 + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npx jest --coverage + + - name: Upload results to Codecov + uses: codecov/codecov-action@v5 + with: + token: \${{ secrets.CODECOV_TOKEN }}${ + orgUploadToken + ? ` + slug: ${owner}/${repo}` + : '' + } +`, + }, + Vitest: { + install: 'npm install --save-dev vitest @vitest/coverage-v8', + run: 'npx vitest run --coverage', + githubActionsWorkflow: `name: Run tests and upload coverage + +on: + push + +jobs: + test: + name: Run tests and collect coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Node + uses: actions/setup-node@v4 + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npx vitest run --coverage + + - name: Upload results to Codecov + uses: codecov/codecov-action@v5 + with: + token: \${{ secrets.CODECOV_TOKEN }}${ + orgUploadToken + ? ` + slug: ${owner}/${repo}` + : '' + } +`, + }, + Pytest: { + install: 'pip install pytest pytest-cov', + run: 'pytest --cov-branch --cov-report=xml', + githubActionsWorkflow: `name: Run tests and upload coverage + +on: + push + +jobs: + test: + name: Run tests and collect coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v4 + + - name: Install dependencies + run: pip install pytest pytest-cov + + - name: Run tests + run: pytest --cov-branch --cov-report=xml + + - name: Upload results to Codecov + uses: codecov/codecov-action@v5 + with: + token: \${{ secrets.CODECOV_TOKEN }}${ + orgUploadToken + ? ` + slug: ${owner}/${repo}` + : '' + } +`, + }, + Go: { + install: undefined, + run: 'go test -coverprofile=coverage.txt', + githubActionsWorkflow: `name: Run tests and upload coverage + +on: + push + +jobs: + test: + name: Run tests and collect coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + + - name: Install dependencies + run: go mod download + + - name: Run tests + run: go test -coverprofile=coverage.txt + + - name: Upload results to Codecov + uses: codecov/codecov-action@v5 + with: + token: \${{ secrets.CODECOV_TOKEN }}${ + orgUploadToken + ? ` + slug: ${owner}/${repo}` + : '' + } +`, + }, + }), + [orgUploadToken, owner, repo] + ) +}