test: move internet presence coverage to client (#68362)

Co-authored-by: sembauke <sembauke@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sem Bauke
2026-08-21 16:56:11 +02:00
committed by GitHub
parent b5af882abf
commit 4d2eb21e6d
3 changed files with 129 additions and 83 deletions
@@ -0,0 +1,99 @@
import { configureStore } from '@reduxjs/toolkit';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { Provider } from 'react-redux';
import { describe, expect, it, vi } from 'vitest';
import type { User } from '../../../redux/prop-types';
import Internet from './internet';
const baseUser = {
githubProfile: '',
linkedin: '',
twitter: '',
bluesky: '',
website: ''
} as User;
const socialFields = [
{
label: 'GitHub',
url: 'https://github.com/certified-user',
checkTestId: 'internet-github-check'
},
{
label: 'LinkedIn',
url: 'https://www.linkedin.com/in/certified-user',
checkTestId: 'internet-linkedin-check'
},
{
label: 'X',
url: 'https://x.com/certified-user',
checkTestId: 'internet-twitter-check'
},
{
label: 'Bluesky',
url: 'https://bsky.app/profile/certified-user.bsky.social',
checkTestId: 'internet-bluesky-check'
},
{
label: 'settings.labels.personal',
url: 'https://certified-user.com',
checkTestId: 'internet-website-check'
}
];
function makeStore() {
return configureStore({
reducer: (state: Record<string, never> = {}) => state
});
}
function renderInternet(userOverrides: Partial<User> = {}) {
const store = makeStore();
return render(
<Provider store={store}>
<Internet
setIsEditing={vi.fn()}
user={{ ...baseUser, ...userOverrides }}
/>
</Provider>
);
}
describe('<Internet />', () => {
it('renders the internet presence form with a disabled save button', () => {
renderInternet();
expect(
screen.getByRole('heading', { name: 'settings.headings.internet' })
).toBeInTheDocument();
expect(
screen.getByRole('group', { name: 'settings.headings.internet' })
).toBeInTheDocument();
expect(
screen.getByRole('button', { name: /buttons\.save/ })
).toHaveAttribute('aria-disabled', 'true');
socialFields.forEach(({ checkTestId }) => {
expect(screen.queryByTestId(checkTestId)).not.toBeInTheDocument();
});
});
it('shows a checkmark for each valid social URL', async () => {
const user = userEvent.setup();
renderInternet();
for (const { label, url, checkTestId } of socialFields) {
await user.type(screen.getByRole('textbox', { name: label }), url);
expect(screen.getByTestId(checkTestId)).toBeInTheDocument();
}
expect(
screen.getByRole('button', { name: /buttons\.save/ })
).not.toHaveAttribute('aria-disabled', 'true');
});
});
@@ -154,7 +154,7 @@ const InternetSettings = ({
<form
id='internet-presence'
onSubmit={handleSubmit}
data-playwright-test-label='internet-presence'
data-testid='internet-presence'
>
<div role='group' aria-label={t('settings.headings.internet')}>
<FormGroup
@@ -165,7 +165,7 @@ const InternetSettings = ({
GitHub
</ControlLabel>
<FormControl
data-playwright-test-label='internet-github-input'
data-testid='internet-github-input'
onChange={createHandleChange('githubProfile')}
placeholder='https://github.com/user-name'
type='url'
@@ -175,7 +175,7 @@ const InternetSettings = ({
<Check
url={formValues.githubProfile}
validation={githubProfileValidation}
dataPlaywrightTestLabel='internet-github-check'
dataTestId='internet-github-check'
/>
<Info message={githubProfileValidationMessage} />
</FormGroup>
@@ -196,7 +196,7 @@ const InternetSettings = ({
<Check
url={formValues.linkedin}
validation={linkedinValidation}
dataPlaywrightTestLabel='internet-linkedin-check'
dataTestId='internet-linkedin-check'
/>
<Info message={linkedinValidationMessage} />
</FormGroup>
@@ -215,7 +215,7 @@ const InternetSettings = ({
<Check
url={formValues.twitter}
validation={twitterValidation}
dataPlaywrightTestLabel='internet-twitter-check'
dataTestId='internet-twitter-check'
/>
<Info message={twitterValidationMessage} />
</FormGroup>
@@ -236,7 +236,7 @@ const InternetSettings = ({
<Check
url={formValues.bluesky}
validation={blueskyValidation}
dataPlaywrightTestLabel='internet-bluesky-check'
dataTestId='internet-bluesky-check'
/>
<Info message={blueskyValidationMessage} />
</FormGroup>
@@ -257,7 +257,7 @@ const InternetSettings = ({
<Check
url={formValues.website}
validation={websiteValidation}
dataPlaywrightTestLabel='internet-website-check'
dataTestId='internet-website-check'
/>
<Info message={websiteValidationMessage} />
</FormGroup>
@@ -279,20 +279,16 @@ const InternetSettings = ({
const Check = ({
url,
validation,
dataPlaywrightTestLabel
dataTestId
}: {
url: string;
validation: URLValidation['state'];
dataPlaywrightTestLabel: string;
dataTestId: string;
}) =>
url && validation === 'success' ? (
<FormControl.Feedback>
<span>
<FontAwesomeIcon
data-playwright-test-label={dataPlaywrightTestLabel}
icon={faCheck}
size='1x'
/>
<FontAwesomeIcon data-testid={dataTestId} icon={faCheck} size='1x' />
</span>
</FormControl.Feedback>
) : null;
+20 -69
View File
@@ -3,16 +3,11 @@ import { test, expect } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json';
const settingsPageElement = {
githubInput: 'internet-github-input',
githubCheckmark: 'internet-github-check',
linkedinCheckmark: 'internet-linkedin-check',
twitterCheckmark: 'internet-twitter-check',
blueskyCheckmark: 'internet-bluesky-check',
personalWebsiteCheckmark: 'internet-website-check',
flashMessageAlert: 'flash-message',
internetPresenceForm: 'internet-presence'
} as const;
const githubUrl = 'https://github.com/certified-user';
test.beforeEach(async ({ page }) => {
// Reset input values
execSync('node ../tools/scripts/seed/seed-demo-user --certified-user');
@@ -24,7 +19,8 @@ test.beforeEach(async ({ page }) => {
test.describe('Your Internet Presence', () => {
test.skip(({ browserName }) => browserName === 'webkit', 'flaky on Safari');
test('should display the section with save button being disabled', async ({
test('should save a social link and keep it after reload', async ({
page
}) => {
await expect(
@@ -34,69 +30,24 @@ test.describe('Your Internet Presence', () => {
})
).toBeVisible();
await expect(
page
.getByTestId(settingsPageElement.internetPresenceForm)
.getByRole('button', { name: translations.buttons.save })
).toBeVisible();
});
const socialInput = page.getByRole('textbox', { name: 'GitHub' });
await expect(socialInput).toBeVisible();
await socialInput.fill(githubUrl);
const socials = [
{
name: 'github',
url: 'https://github.com/certified-user',
label: 'GitHub',
checkTestId: settingsPageElement.githubCheckmark
},
{
name: 'linkedin',
url: 'https://www.linkedin.com/in/certified-user',
label: 'LinkedIn',
checkTestId: settingsPageElement.linkedinCheckmark
},
{
name: 'twitter',
url: 'https://x.com/certified-user',
label: 'X',
checkTestId: settingsPageElement.twitterCheckmark
},
{
name: 'bluesky',
url: 'https://bsky.app/profile/certified-user.bsky.social',
label: 'Bluesky',
checkTestId: settingsPageElement.blueskyCheckmark
},
{
name: 'website',
url: 'https://certified-user.com',
label: translations.settings.labels.personal,
checkTestId: settingsPageElement.personalWebsiteCheckmark
}
];
const saveButton = page
.locator(`[data-testid="${settingsPageElement.internetPresenceForm}"]`)
.getByRole('button', { name: translations.buttons.save });
socials.forEach(social => {
test(`should hide ${social.name} checkmark by default`, async ({
page
}) => {
await expect(page.getByTestId(social.checkTestId)).toBeHidden();
});
await expect(saveButton).toBeVisible();
await saveButton.click();
await expect(page.getByRole('alert').first()).toContainText(
'We have updated your social links'
);
test(`should update ${social.name} URL`, async ({ page }) => {
const socialInput = page.getByRole('textbox', { name: social.label });
await expect(socialInput).toBeVisible();
await socialInput.fill(social.url);
const socialCheckmark = page.getByTestId(social.checkTestId);
await expect(socialCheckmark).toBeVisible();
const saveButton = page
.getByTestId(settingsPageElement.internetPresenceForm)
.getByRole('button', { name: translations.buttons.save });
await expect(saveButton).toBeVisible();
await saveButton.click();
await expect(page.getByRole('alert').first()).toContainText(
'We have updated your social links'
);
});
await page.reload();
await page.getByRole('button', { name: 'Edit my profile' }).click();
await expect(page.getByRole('textbox', { name: 'GitHub' })).toHaveValue(
githubUrl
);
});
});