Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ The report covers:

## What is PatchWave?

PatchWave is a GitHub app that automatically analyzes, fixes and merges your Dependabot PRs. It's free for 30 days, up to 100 PRs, no credit card.
PatchWave is a GitHub app that automatically analyzes, fixes and merges your Dependabot PRs. Everyone gets 25 free PRs every month. No credit card required.

- [Join the public beta](https://app.patchwave.ai/join?utm_source=patchwave-analysis&utm_medium=readme)
Paid plans start at $10 a month for 35 PRs total, including your 25 free PRs. All plans include analysis, fixing, and unlimited repositories and users. Only unused paid PRs roll over for one month. See [pricing](https://patchwave.ai/pricing) for larger allowances and volume discounts.

- [Sign up for free](https://app.patchwave.ai/join?utm_source=patchwave-analysis&utm_medium=readme)
- [Learn more at patchwave.ai](https://patchwave.ai/?utm_source=patchwave-analysis&utm_medium=readme)

## What it reads from GitHub
Expand Down
22 changes: 13 additions & 9 deletions src/report/web/App.browser.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
personActivity,
prBacklog,
} from '../testFactories.ts';
import { automatedStoryCopy, automatedStorySectionId, automatedStoryTestIds } from './acts/AutomatedStory.tsx';
import { automatedStorySectionId, automatedStoryTestIds } from './acts/AutomatedStory.tsx';
import { callToActionCopy, callToActionTestIds } from './acts/CallToAction.tsx';
import { costStoryCopy, costStoryTestIds } from './acts/CostStory.tsx';
import { methodologyAppendixTestIds } from './acts/MethodologyAppendix.tsx';
Expand Down Expand Up @@ -552,24 +552,28 @@ describe('sections and calls to action', () => {
expect(cta).toHaveAttribute('href', href);
});

it('labels the automation CTA with the savings shown above it', () => {
it('offers free signup with monthly PR terms in both signup sections', () => {
renderReport();

const savings = screen.getByTestId(automatedStoryTestIds.patchwaveCost).textContent ?? '';
const cta = screen.getByTestId(automatedStoryTestIds.primaryCta);
expect(cta).toHaveTextContent(automatedStoryCopy.ctaLabel(savings));
expect(cta).toHaveAttribute('href', reportCtaUrls.automation);
expect(screen.getByTestId(automatedStoryTestIds.primaryCta)).toHaveTextContent('Sign up for free');
expect(screen.getByTestId(automatedStoryTestIds.primaryCta)).toHaveAttribute('href', reportCtaUrls.automation);
expect(screen.getByTestId(automatedStoryTestIds.section)).toHaveTextContent(
'25 free PRs every month. No credit card required.',
);
expect(screen.getByTestId(callToActionTestIds.cta)).toHaveTextContent('Sign up for free');
expect(screen.getByTestId(callToActionTestIds.section)).toHaveTextContent('25 free PRs every month.');
expect(screen.getByTestId(callToActionTestIds.section)).toHaveTextContent('No credit card required.');
});

it('drops the savings from the automation CTA when there is nothing to save', () => {
it('offers free signup even when there is nothing to save', () => {
renderReport({
costEstimate: costEstimate.build({ humanMergeCount: 0, humanReviewCount: 0 }),
});

expect(screen.getByTestId(automatedStoryTestIds.primaryCta)).toHaveTextContent(automatedStoryCopy.ctaFallbackLabel);
expect(screen.getByTestId(automatedStoryTestIds.primaryCta)).toHaveTextContent('Sign up for free');
});

it('sends trial CTAs to sign-up and the header to the homepage, tagged with UTM parameters', () => {
it('sends signup CTAs to sign-up and the header to the homepage, tagged with UTM parameters', () => {
expect(reportCtaUrls.automation).toBe(
'https://app.patchwave.ai/join?utm_source=patchwave-analysis&utm_medium=report&utm_content=automation',
);
Expand Down
9 changes: 3 additions & 6 deletions src/report/web/acts/AutomatedStory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ export const automatedStoryTestIds = {
export const automatedStorySectionId = 'patchwave';

export const automatedStoryCopy = {
ctaLabel: (savings: string) => `Start saving ${savings}`,
ctaFallbackLabel: 'Join the public beta',
ctaNote: 'Free for 30 days. No credit card.',
ctaLabel: 'Sign up for free',
ctaNote: '25 free PRs every month. No credit card required.',
} as const;

const SHARE_MIN = 50;
Expand Down Expand Up @@ -114,9 +113,7 @@ export function AutomatedStory() {
<div className="mt-7 flex flex-wrap items-center gap-x-6 gap-y-3 no-print">
<Button asChild variant="pixel" cursor>
<a data-testid={automatedStoryTestIds.primaryCta} href={reportCtaUrls.automation}>
{savings.hours >= 1
? automatedStoryCopy.ctaLabel(formatAmount(savings, '/yr'))
: automatedStoryCopy.ctaFallbackLabel}
{automatedStoryCopy.ctaLabel}
</a>
</Button>
<p className="text-muted-foreground m-0 text-sm">{automatedStoryCopy.ctaNote}</p>
Expand Down
8 changes: 4 additions & 4 deletions src/report/web/acts/CallToAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export const callToActionTestIds = {
export const callToActionCopy = {
heading: 'Wave goodbye to (most) dependency update work.',
pitch: 'PatchWave is a GitHub app that automatically analyzes, fixes and merges your Dependabot PRs.',
trialTerms: 'Free for 30 days, up to 100 PRs.',
ctaLabel: 'Join the public beta',
ctaNote: 'No credit card. The 30 days start when you install the GitHub App.',
freeTerms: '25 free PRs every month.',
ctaLabel: 'Sign up for free',
ctaNote: 'No credit card required.',
howItWorksLabel: 'See how it works',
} as const;

Expand All @@ -36,7 +36,7 @@ export function CallToAction() {
</h2>
<p className="m-0 max-w-2xl text-lg leading-relaxed text-balance sm:text-xl">{callToActionCopy.pitch}</p>
<p className="text-brand-butter m-0 text-2xl leading-tight font-bold text-balance">
{callToActionCopy.trialTerms}
{callToActionCopy.freeTerms}
</p>
<div className="mt-4 grid justify-items-center gap-4">
<Button asChild variant="sun" cursor>
Expand Down
Loading