From 4707901305a09154c47248e3432d10b9ef87cf42 Mon Sep 17 00:00:00 2001 From: "Mr.Hope" Date: Wed, 31 Jan 2024 12:00:42 +0800 Subject: [PATCH] test(e2e): add tests --- e2e/docs/.vuepress/config.ts | 4 +- e2e/docs/seo/README.md | 31 ++++++++ e2e/tests/plugin-seo/seo.cy.ts | 71 +++++++++++++++++++ plugins/plugin-seo/src/node/appendSEO.ts | 6 ++ .../src/node/generateDescription.ts | 2 +- .../plugin-seo/src/node/utils/getImages.ts | 24 +++---- themes/theme-default/src/shared/options.ts | 4 +- 7 files changed, 124 insertions(+), 18 deletions(-) create mode 100644 e2e/docs/seo/README.md create mode 100644 e2e/tests/plugin-seo/seo.cy.ts diff --git a/e2e/docs/.vuepress/config.ts b/e2e/docs/.vuepress/config.ts index 584e3522e0..6a556cf0ea 100644 --- a/e2e/docs/.vuepress/config.ts +++ b/e2e/docs/.vuepress/config.ts @@ -40,7 +40,7 @@ export default defineUserConfig({ bundler: E2E_BUNDLER === 'webpack' ? webpackBundler() : viteBundler(), theme: defaultTheme({ - hostname: 'https://e2e-test.com', + hostname: 'https://ecosystem-e2e-test.com', logo: 'https://v2.vuepress.vuejs.org/images/hero.png', navbar: [ { @@ -59,7 +59,6 @@ export default defineUserConfig({ ], sidebar: { - '/': ['/sidebar/'], '/sidebar/heading/': 'heading', '/sidebar/config/': [ { @@ -71,6 +70,7 @@ export default defineUserConfig({ ], }, ], + '/': [], }, themePlugins: { diff --git a/e2e/docs/seo/README.md b/e2e/docs/seo/README.md new file mode 100644 index 0000000000..58eb2842a4 --- /dev/null +++ b/e2e/docs/seo/README.md @@ -0,0 +1,31 @@ +--- +title: SEO Demo Page +author: Mr.Hope +date: 2021-01-01 +category: + - Demo +tag: + - Demo +--- + +Here is **article excerpt**. + +```js +const a = 1; +``` + + + +## Content + +![alt](/logo.png) + +Here is main content of **article**. + +1. A +1. B +1. C + +```js +const a = 1; +``` diff --git a/e2e/tests/plugin-seo/seo.cy.ts b/e2e/tests/plugin-seo/seo.cy.ts new file mode 100644 index 0000000000..9921b97046 --- /dev/null +++ b/e2e/tests/plugin-seo/seo.cy.ts @@ -0,0 +1,71 @@ +describe('seo', () => { + const BASE = Cypress.env('E2E_BASE') + + it('have OGP', () => { + cy.visit('/seo/') + + cy.get('head meta[property="og:url"]').should( + 'have.attr', + 'content', + `https://ecosystem-e2e-test.com${BASE}seo/`, + ) + cy.get('head meta[property="og:site_name"]').should( + 'have.attr', + 'content', + 'VuePress Ecosystem E2E', + ) + cy.get('head meta[property="og:title"]').should( + 'have.attr', + 'content', + 'SEO Demo Page', + ) + cy.get('head meta[property="og:description"]').should( + 'have.attr', + 'content', + 'Here is article excerpt. Content alt Here is main content of article. A B C ', + ) + cy.get('head meta[property="og:type"]').should( + 'have.attr', + 'content', + 'article', + ) + cy.get('head meta[property="og:locale"]').should( + 'have.attr', + 'content', + 'en-US', + ) + cy.get('head meta[property="article:author"]').should( + 'have.attr', + 'content', + 'Mr.Hope', + ) + cy.get('head meta[property="article:tag"]').should( + 'have.attr', + 'content', + 'Demo', + ) + cy.get('head meta[property="article:published_time"]').should( + 'have.attr', + 'content', + '2021-01-01T00:00:00.000Z', + ) + }) + + it('have JSONLD', () => { + cy.visit('/seo/') + + cy.get('head script[type="application/ld+json"]').then((el) => { + const json = JSON.parse(el[0].innerText) + + expect(json).to.deep.equal({ + '@context': 'https://schema.org', + '@type': 'Article', + 'headline': 'SEO Demo Page', + 'image': [`https://ecosystem-e2e-test.com${BASE}logo.png`], + 'datePublished': '2021-01-01T00:00:00.000Z', + 'dateModified': null, + 'author': [{ '@type': 'Person', 'name': 'Mr.Hope' }], + }) + }) + }) +}) diff --git a/plugins/plugin-seo/src/node/appendSEO.ts b/plugins/plugin-seo/src/node/appendSEO.ts index c22170275d..34c861ec4e 100644 --- a/plugins/plugin-seo/src/node/appendSEO.ts +++ b/plugins/plugin-seo/src/node/appendSEO.ts @@ -11,6 +11,7 @@ import { getJSONLDInfo } from './getJSONLDInfo.js' import { getOGPInfo } from './getOGPInfo.js' import type { SeoPluginOptions } from './options.js' import { getAlternateLinks, getCanonicalLink } from './utils/getLinks.js' +import { logger } from './utils/index.js' export const appendSEO = (app: App, options: SeoPluginOptions): void => { app.pages.forEach((page: ExtendPage) => { @@ -34,6 +35,11 @@ export const appendSEO = (app: App, options: SeoPluginOptions): void => { ? options.jsonLd(defaultJSONLD, page, app) : defaultJSONLD + if (app.env.isDebug) { + logger.info(`OGP of ${page.path}:`, ogpContent) + logger.info(`JSON-LD of ${page.path}:`, ogpContent) + } + addOGP(head, ogpContent) appendJSONLD(head, jsonLDContent) diff --git a/plugins/plugin-seo/src/node/generateDescription.ts b/plugins/plugin-seo/src/node/generateDescription.ts index 311ad4fcf3..daa8b11a72 100644 --- a/plugins/plugin-seo/src/node/generateDescription.ts +++ b/plugins/plugin-seo/src/node/generateDescription.ts @@ -9,7 +9,7 @@ export const generateDescription = ( ): void => { // generate description if (!page.frontmatter.description && autoDescription) { - const pageText = getPageText(app, page, { length: 180 }) + const pageText = getPageText(app, page, { length: 180, singleLine: true }) page.frontmatter.description = pageText.length > 180 ? `${pageText.slice(0, 177)}...` : pageText diff --git a/plugins/plugin-seo/src/node/utils/getImages.ts b/plugins/plugin-seo/src/node/utils/getImages.ts index bb141ed91a..5e176637f7 100644 --- a/plugins/plugin-seo/src/node/utils/getImages.ts +++ b/plugins/plugin-seo/src/node/utils/getImages.ts @@ -4,23 +4,21 @@ import type { ExtendPage } from '../../typings/index.js' import type { SeoPluginOptions } from '../options.js' import { getUrl } from './getUrl.js' +const IMAGE_REG_EXP = /!\[.*?\]\((.*?)\)/gu + export const getImages = ( { content }: ExtendPage, { options: { base } }: App, { hostname }: SeoPluginOptions, -): string[] => { - const result = /!\[.*?\]\((.*?)\)/giu.exec(content) - - if (result) - return result - .map(([, link]) => { - if (isAbsoluteUrl(link)) return getUrl(hostname, base, link) +): string[] => + Array.from(content.matchAll(IMAGE_REG_EXP)) + .map(([, link]) => { + console.log(link) - if (isUrl(link)) return link + if (isAbsoluteUrl(link)) return getUrl(hostname, base, link) - return null - }) - .filter((item): item is string => item !== null) + if (isUrl(link)) return link - return [] -} + return null + }) + .filter((item): item is string => item !== null) diff --git a/themes/theme-default/src/shared/options.ts b/themes/theme-default/src/shared/options.ts index e80216c6f1..301e9871c1 100644 --- a/themes/theme-default/src/shared/options.ts +++ b/themes/theme-default/src/shared/options.ts @@ -1,4 +1,4 @@ -import type { SeoOptions } from '@vuepress/plugin-seo' +import type { SeoPluginOptions } from '@vuepress/plugin-seo' import type { SitemapPluginOptions } from '@vuepress/plugin-sitemap' import type { ThemeData } from '@vuepress/plugin-theme-data' import type { LocaleData } from 'vuepress/shared' @@ -55,7 +55,7 @@ export interface DefaultThemePluginsOptions { /** * Enable @vuepress/plugin-seo or not */ - seo?: Partial | boolean + seo?: Partial | boolean /** * Enable @vuepress/plugin-sitemap or not