Skip to content

Commit

Permalink
ci/e2e tests against mobile (freeCodeCamp#55347)
Browse files Browse the repository at this point in the history
Co-authored-by: sembauke <[email protected]>
  • Loading branch information
ojeytonwilliams and Sembauke authored Jul 3, 2024
1 parent 65ee5c6 commit 5b62ec7
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 56 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/e2e-playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ jobs:
strategy:
fail-fast: false
matrix:
browsers: [chromium, firefox, webkit]
# Not Mobile Safari until we can get it working. Webkit and Mobile
# Chrome both work, so hopefully there are no Mobile Safari specific
# bugs.
browsers: [chromium, firefox, webkit, Mobile Chrome]
node-version: [20.x]

services:
Expand Down Expand Up @@ -143,7 +146,7 @@ jobs:
run: |
pnpm run start-ci &
sleep 10
npx playwright test --project=${{ matrix.browsers }} --grep-invert 'third-party-donation.spec.ts'
npx playwright test --project="${{ matrix.browsers }}" --grep-invert 'third-party-donation.spec.ts'
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
Expand Down
1 change: 1 addition & 0 deletions client/src/templates/Challenges/classic/mobile-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ class MobileLayout extends Component<MobileLayoutProps, MobileLayoutState> {
<TabsContent
tabIndex={-1}
className='tab-content'
data-playwright-test-label='preview-pane'
value={tabs.preview}
forceMount
// forceMount causes the preview tabpanel to never be hidden,
Expand Down
40 changes: 27 additions & 13 deletions e2e/challenge-reset-modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,29 @@ test('should render the modal content correctly', async ({ page }) => {
});

test('User can reset challenge', async ({ page, isMobile, browserName }) => {
const initialText = 'CatPhotoApp';
const initialFrame = page
.frameLocator('iframe[title="challenge preview"]')
const initialText = ' <h2>Cat Photos</h2>';
const initialEditorText = page
.getByTestId('editor-container-indexhtml')
.getByText(initialText);

const updatedText = 'Only Dogs';
const updatedFrame = page
.frameLocator('iframe[title="challenge preview"]')
const updatedEditorText = page
.getByTestId('editor-container-indexhtml')
.getByText(updatedText);

await page.goto(
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-3'
);

// Building the preview can take a while
await expect(initialFrame).toBeVisible({ timeout: 10000 });
await expect(initialEditorText).toBeVisible();

// Modify the text in the editor pane, clearing first, otherwise the existing
// text will be selected before typing
await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });
await getEditors(page).fill(updatedText);
await expect(updatedFrame).toBeVisible({ timeout: 10000 });
await expect(updatedEditorText).toBeVisible();

// Run the tests so the lower jaw updates (later we confirm that the update
// are reset)
Expand All @@ -89,7 +89,7 @@ test('User can reset challenge', async ({ page, isMobile, browserName }) => {
.click();

// Check it's back to the initial state
await expect(initialFrame).toBeVisible({ timeout: 10000 });
await expect(initialEditorText).toBeVisible();
await expect(
page.getByText(translations.learn['sorry-keep-trying'])
).not.toBeVisible();
Expand All @@ -101,7 +101,7 @@ test('User can reset classic challenge', async ({ page, isMobile }) => {
);

const challengeSolution = '// This is in-line comment';

await focusEditor({ page, isMobile });
await getEditors(page).fill(challengeSolution);

const submitButton = page.getByRole('button', {
Expand All @@ -112,16 +112,25 @@ test('User can reset classic challenge', async ({ page, isMobile }) => {
await expect(
page.locator('.view-lines').getByText(challengeSolution)
).toBeVisible();

if (isMobile) {
await page
.getByText(translations.learn['editor-tabs'].instructions)
.click();
}

await expect(
page.getByLabel(translations.icons.passed).locator('circle')
).toBeVisible();
await expect(
page.getByText(translations.learn['tests-completed'])
).toBeVisible();

await page
.getByRole('button', { name: translations.buttons['reset-lesson'] })
.getByRole('button', {
name: !isMobile
? translations.buttons['reset-lesson']
: translations.buttons.reset
})
.click();

await page
.getByRole('button', { name: translations.buttons['reset-lesson'] })
.click();
Expand All @@ -135,6 +144,11 @@ test('User can reset classic challenge', async ({ page, isMobile }) => {
await expect(
page.getByText(translations.learn['tests-completed'])
).not.toBeVisible();

if (isMobile) {
await page.getByText(translations.learn['editor-tabs'].console).click();
}

await expect(page.getByText(translations.learn['test-output'])).toBeVisible();
});

Expand Down
1 change: 1 addition & 0 deletions e2e/code-storage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getEditors } from './utils/editor';

test.use({ storageState: 'playwright/.auth/certified-user.json' });
test.describe('Challenge with editor', function () {
test.skip(({ isMobile }) => isMobile);
test('the shortcut "Ctrl + S" saves the code', async ({ page }) => {
await page.goto(
'/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-2'
Expand Down
15 changes: 11 additions & 4 deletions e2e/editor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { APIRequestContext, expect, test } from '@playwright/test';

import { clearEditor, focusEditor } from './utils/editor';
import { clearEditor, focusEditor, getEditors } from './utils/editor';
import { authedRequest } from './utils/request';

const setTheme = async (
Expand Down Expand Up @@ -41,15 +41,22 @@ test.describe('Python Terminal', () => {
);

await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });
await clearEditor({ page, browserName, isMobile });
// Then enter invalid code
await page.keyboard.insertText('def');
await getEditors(page).fill('def');

if (isMobile) {
await page.getByRole('tab', { name: 'Preview' }).click();
}

const preview = page.getByTestId('preview-pane');

// While it's displayed on multiple lines, the string itself has no newlines, hence:
const error = `Traceback (most recent call last): File "main.py", line 1 def ^SyntaxError: invalid syntax`;
// It shouldn't take this long, but the Python worker can be slow to respond.
await expect(preview).toContainText(error, { timeout: 15000 });
await expect(preview.getByText(error)).toContainText(error, {
timeout: 15000
});
});
});

Expand Down
2 changes: 1 addition & 1 deletion e2e/help-button.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ test.describe('help-button tests for a page with a reset and help button', () =>
page
}) => {
await page.goto(
'learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-8'
'learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-3'
);
const checkButton = page.getByTestId('lowerJaw-check-button');
await checkButton.click();
Expand Down
3 changes: 3 additions & 0 deletions e2e/hotkeys.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ test.afterEach(
})
);

// TODO: handle keyboard shortcuts on mobile
test.skip(({ isMobile }) => isMobile, 'Only test on desktop');

test('User can use shortcuts in and around the editor', async ({ page }) => {
await page.goto(links.basicJS1);

Expand Down
9 changes: 7 additions & 2 deletions e2e/multifile-cert-projects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ test.describe('multifileCertProjects', () => {
await page.keyboard.type('save1text');
await expect(page.getByText('save1text')).toBeVisible();

await page.getByRole('button', { name: 'Save your Code' }).click();
await page
.getByRole('button', { name: !isMobile ? 'Save your Code' : 'Save' })
.click();

await expect(page.getByTestId('flash-message')).toContainText(success);

await page.reload();

await focusEditor({ page, isMobile });

await expect(page.getByText('save1text')).toBeVisible();
});

Expand All @@ -40,6 +44,8 @@ test.describe('multifileCertProjects', () => {
isMobile,
browserName
}) => {
test.skip(isMobile);

await focusEditor({ page, isMobile });
await clearEditor({ page, browserName });

Expand All @@ -58,7 +64,6 @@ test.describe('multifileCertProjects', () => {
await page.reload();

await expect(page.getByText('save2text')).toBeVisible();

await focusEditor({ page, isMobile });

await page.keyboard.down('Control');
Expand Down
Loading

0 comments on commit 5b62ec7

Please sign in to comment.