diff --git a/concourse/book-scan/script.bash b/concourse/book-scan/script.bash index 4ebd30710a..3fff4a8f6e 100755 --- a/concourse/book-scan/script.bash +++ b/concourse/book-scan/script.bash @@ -6,6 +6,6 @@ cloudfront_environment=$(< cloudfront-environment/version.txt) cd rex-web -yarn +yarn install --network-timeout 60000 node script/entry.js domVisitor errorsExist --rootUrl="https://$cloudfront_environment" --queryString="validateLinks" diff --git a/concourse/create-test-plan-configs/task.yml b/concourse/create-test-plan-configs/task.yml index 41e2419d3d..861594db39 100644 --- a/concourse/create-test-plan-configs/task.yml +++ b/concourse/create-test-plan-configs/task.yml @@ -30,5 +30,5 @@ run: - | DEST=$(pwd)/test-plans cd rex-web/concourse/create-test-plan-configs - yarn install + yarn install --network-timeout 60000 ./script.js $DEST diff --git a/concourse/lighthouse/script.bash b/concourse/lighthouse/script.bash new file mode 100755 index 0000000000..bbe032aee1 --- /dev/null +++ b/concourse/lighthouse/script.bash @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euxo pipefail + +base_dir=$(pwd) + +cd rex-web + +yarn install --network-timeout 60000 + +node script/entry.js lighthouse --pages="$LIGHTHOUSE_PAGES" \ + --mostRecentReportDir="$base_dir/$LIGHTHOUSE_MOST_RECENT_REPORT_DIR" \ + --reportDir="$base_dir/$LIGHTHOUSE_REPORT_DIR" diff --git a/concourse/lighthouse/task.yml b/concourse/lighthouse/task.yml new file mode 100644 index 0000000000..bd11e11979 --- /dev/null +++ b/concourse/lighthouse/task.yml @@ -0,0 +1,26 @@ +--- +platform: linux + +image_resource: + type: docker-image + source: + password: ((dockerhub-password)) + username: ((dockerhub-username)) + repository: openstax/rex-web + tag: CI-2023-08-10 + +inputs: +- name: rex-web +- name: most-recent-lighthouse-report +outputs: +- name: lighthouse-report + +params: + AWS_ACCESS_KEY_ID: ((prod-aws-access-key-id)) + AWS_SECRET_ACCESS_KEY: ((prod-aws-secret-access-key)) + LIGHTHOUSE_PAGES: ((lighthouse-pages)) + LIGHTHOUSE_MOST_RECENT_REPORT_DIR: most-recent-lighthouse-report + LIGHTHOUSE_REPORT_DIR: lighthouse-report + +run: + path: rex-web/concourse/lighthouse/script.bash diff --git a/package.json b/package.json index 853baf33e9..020c3dd526 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "test:prerender:specs": "REACT_APP_ENV=test SERVER_MODE=built jest --testPathPattern=\"(\\.|/)prerenderspec\\.tsx?\" --config jest-puppeteer.config.json", "test:prerender:browser": "REACT_APP_ENV=test SERVER_MODE=built jest --testPathPattern=\"(\\.|/)browserspec\\.tsx?\" --config jest-puppeteer.config.json -i", "test:prerender:screenshots": "REACT_APP_ENV=test SERVER_MODE=built jest --testPathPattern=\"(\\.|/)screenshotspec\\.tsx?\" --config jest-puppeteer.config.json", - "test:lighthouse-manual": "REACT_APP_ENV=test lighthouse --view --config-path=./src/test/audits/index.js", + "test:lighthouse:manual": "REACT_APP_ENV=test lighthouse --view --config-path=./src/test/audits/index.js", "analyze:bundle": "craco build && source-map-explorer 'build/static/js/*.js' -m", "analyze:dom": "node ./script/entry.js domVisitor", "heroku-postbuild": "npm run-script build:clean" diff --git a/playwright/src/fixtures/content.page.ts b/playwright/src/fixtures/content.page.ts index f47c972a8d..191bfd2dff 100644 --- a/playwright/src/fixtures/content.page.ts +++ b/playwright/src/fixtures/content.page.ts @@ -90,6 +90,13 @@ class ContentPage { .addCookies([{ name: 'nudge_study_guides_date', value: current_date, url: this.page.url() }]) } + async canonical() { + // Return canonical link of the current page + let canonicalPageSelector = await this.page.$('[rel="canonical"]') + const canonicalPage = await canonicalPageSelector.evaluate((e) => e.getAttribute('href')) + return canonicalPage + } + async colorLocator(color: string) { // Return locator of the color if (color === 'blue') { diff --git a/playwright/src/fixtures/toc.ts b/playwright/src/fixtures/toc.ts index 0b5f52c447..06e60a8584 100644 --- a/playwright/src/fixtures/toc.ts +++ b/playwright/src/fixtures/toc.ts @@ -89,7 +89,7 @@ class TOC { if ((await titleAfterClick) != (await titleBeforeClick)) { return } else { - sleep(1) + sleep(2) } } else { console.log('The page number specified exceeds the total pages in the book') diff --git a/playwright/tests/rex-test/rex.behaviorspec.ts b/playwright/tests/rex-test/rex.behaviorspec.ts index dc254353e1..29b73b1a7b 100644 --- a/playwright/tests/rex-test/rex.behaviorspec.ts +++ b/playwright/tests/rex-test/rex.behaviorspec.ts @@ -576,3 +576,101 @@ test('MH page dropdown filters', async ({ page, isMobile }) => { const highlightcount = await bookPage.highlightCount() expect(highlightcount).toBe(2) }) + + +test('C543224 canonicals for books with no shared content', async ({ page, isMobile, browserName }) => { + test.skip(isMobile as boolean, 'test only desktop resolution') + test.skip(browserName == 'webkit', 'test only chrome') + test.skip(browserName == 'firefox', 'test only chrome') + + // GIVEN: Open Rex page + const bookPage = new ContentPage(page) + const path = '/books/chemistry-2e/pages/1-1-chemistry-in-context' + await bookPage.open(path) + + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/chemistry-2e/pages/1-1-chemistry-in-context') + + // WHEN: click EOC page + const Toc = new TOC(page) + await Toc.pageClick(9) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/chemistry-2e/pages/1-key-equations') + + // WHEN: Click EOB page + await Toc.pageClick(221) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/chemistry-2e/pages/e-water-properties') + + // WHEN: click nested EOB page + await Toc.pageClick(230) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/chemistry-2e/pages/chapter-1') +}) + + +test('C543225 canonicals for pages derived from another book', async ({ page, isMobile, browserName }) => { + test.skip(isMobile as boolean, 'test only desktop resolution') + test.skip(browserName == 'webkit', 'test only chrome') + test.skip(browserName == 'firefox', 'test only chrome') + + // GIVEN: Open Rex page derived from another book + const bookPage = new ContentPage(page) + const path = '/books/preparing-for-college-success/pages/2-1-why-college' + await bookPage.open(path) + + // THEN: Canonical page points to original content + expect(await bookPage.canonical()).toBe('https://openstax.org/books/college-success-concise/pages/1-1-why-college') + + // WHEN: click EOC page from a chapter derived from another book + const Toc = new TOC(page) + await Toc.pageClick(14) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/preparing-for-college-success/pages/2-summary') + + + // WHEN: Open page unique to this book + await Toc.pageClick(3) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/preparing-for-college-success/pages/1-2-your-academic-journey-and-personal-story') + + // WHEN: Open EOC page from the chapter unique to this book + await Toc.pageClick(6) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/preparing-for-college-success/pages/1-family-friends-matter') + + // WHEN: Open EOB page from the chapter unique to this book + await Toc.pageClick(71) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/preparing-for-college-success/pages/index') +}) + +test('C543225 canonicals for old editions point to the latest edition', async ({ page, isMobile, browserName }) => { + test.skip(isMobile as boolean, 'test only desktop resolution') + test.skip(browserName == 'webkit', 'test only chrome') + test.skip(browserName == 'firefox', 'test only chrome') + + // GIVEN: Open older edition of Rex page derived from another book + const bookPage = new ContentPage(page) + const path = '/books/principles-macroeconomics-2e/pages/1-introduction' + await bookPage.open(path) + // THEN: Canonical page points to latest edition of the original content + expect(await bookPage.canonical()).toBe('https://openstax.org/books/principles-economics-3e/pages/1-introduction') + + // WHEN: Open older edition of EOC page of a book derived from another book + const Toc = new TOC(page) + await Toc.pageClick(7) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/principles-macroeconomics-2e/pages/1-key-concepts-and-summary') + + // WHEN: Open older edition of nested EOB page of a book derived from another book + await Toc.pageClick(243) + // THEN: Canonical page points to itself + expect(await bookPage.canonical()).toBe('https://openstax.org/books/principles-macroeconomics-2e/pages/chapter-2') + + + // WHEN: Open older edition of appendix page of a book derived from another book + await Toc.pageClick(241) + // THEN: Canonical page points to latest edition of the original content + expect(await bookPage.canonical()).toBe('https://openstax.org/books/principles-economics-3e/pages/d-the-expenditure-output-model') +}) diff --git a/public/index.html b/public/index.html index f544983b2d..6832197527 100644 --- a/public/index.html +++ b/public/index.html @@ -10,26 +10,8 @@ --> - - - + -