diff --git a/test/helpers/head.js b/test/helpers/head.js
new file mode 100644
index 0000000..d6415db
--- /dev/null
+++ b/test/helpers/head.js
@@ -0,0 +1,97 @@
+import {
+ isValidHttpUrl,
+ isValidImageUrl,
+ isNonEmptyString,
+ isPositiveNumberString
+} from '~/helpers/check-types.js'
+
+export const headPropertyTypes = {
+ 'meta[charset]': {
+ charset: isNonEmptyString
+ },
+
+ //
+ 'meta[name="viewport"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'meta[property="og:image"]': {
+ content: isValidImageUrl
+ },
+
+ //
+ 'meta[property="og:image:width"]': {
+ content: isPositiveNumberString
+ },
+
+ //
+ 'meta[property="og:image:height"]': {
+ content: isPositiveNumberString
+ },
+
+ //
+ 'meta[property="og:image:alt"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'meta[property="twitter:card"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'meta[property="twitter:title"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'meta[property="twitter:description"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'meta[property="twitter:url"]': {
+ content: isValidHttpUrl
+ },
+
+ //
+ 'meta[property="twitter:image"]': {
+ content: isValidImageUrl,
+ },
+
+ //
+ 'meta[name="description"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'meta[property="twitter:title"]': {
+ content: isNonEmptyString
+ },
+
+ //
+ 'link[rel="icon"]': {
+ href: isNonEmptyString
+ },
+
+ //
+ //
+ //
+ //
+ //
+ 'link[rel="preconnect"]': {
+ href: isValidHttpUrl
+ },
+
+ //
+ 'link[rel="preload"]': {
+ as: isNonEmptyString,
+ href: isValidHttpUrl,
+ media: isNonEmptyString,
+ imagesrcset: isNonEmptyString,
+ type: isNonEmptyString,
+
+ count: false
+ },
+}
diff --git a/test/listings/index.js b/test/listings/index.js
index 2a83675..e36f88d 100644
--- a/test/listings/index.js
+++ b/test/listings/index.js
@@ -4,16 +4,13 @@ import test from 'ava'
import axios from 'axios'
import { JSDOM } from 'jsdom'
-import {
- isValidHttpUrl,
- isValidImageUrl,
- isNonEmptyString,
- isPositiveNumberString
-} from '~/helpers/check-types.js'
+
import {
makeApiPathFromEndpoint,
+ getVideoImages,
ListingDetails
} from '~/helpers/listing-page.js'
+import { headPropertyTypes } from '~/test/helpers/head.js'
import { PageHead } from '~/helpers/config.js'
@@ -24,18 +21,21 @@ const listingsCases = {
'/app/spotify': {
endpoint: '/app/spotify',
apiEndpointPath: '/api/app/spotify.json',
+ expectInitialVideo: true,
},
// Electron
'/app/electron-framework': {
endpoint: '/app/electron-framework',
apiEndpointPath: '/api/app/electron-framework.json',
+ expectInitialVideo: false,
},
// Express VPN Benchmarks
'/app/expressvpn/benchmarks/': {
endpoint: '/app/expressvpn/benchmarks/',
apiEndpointPath: '/api/app/expressvpn.json',
+ expectInitialVideo: true,
}
}
@@ -85,7 +85,6 @@ function parseHTML ( htmlString ) {
test( 'Listings have valid api endpoints', async t => {
const { listingsDetails } = t.context
-
for ( const [ caseEndpoint, listingCase ] of listingCaseEntries ) {
const apiPath = listingsDetails[ caseEndpoint ].apiEndpointPath
@@ -94,86 +93,39 @@ test( 'Listings have valid api endpoints', async t => {
}
})
+test( 'Listings with videos have preload data for initialVideo', async t => {
+ const { listingsDetails } = t.context
-const headPropertyTypes = {
- 'meta[charset]': {
- charset: isNonEmptyString
- },
+ for ( const [ caseEndpoint, listingCase ] of listingCaseEntries ) {
- //
- 'meta[name="viewport"]': {
- content: isNonEmptyString
- },
+ const listingDetails = listingsDetails[ caseEndpoint ]
- //
- 'meta[property="og:image"]': {
- content: isValidImageUrl
- },
+ t.assert( listingDetails.hasInitialVideo === listingCase.expectInitialVideo, `${ caseEndpoint } has initial video` )
- //
- 'meta[property="og:image:width"]': {
- content: isPositiveNumberString
- },
+ // Stop here if we don't have an initial video
+ if ( !listingDetails.hasInitialVideo ) continue
- //
- 'meta[property="og:image:height"]': {
- content: isPositiveNumberString
- },
+ // t.log('listingDetails.initialVideo', listingDetails.initialVideo)
- //
- 'meta[property="og:image:alt"]': {
- content: isNonEmptyString
- },
+ // Get headProperties for image preloading
+ const preloadHeadChecks = headPropertyTypes[ 'link[rel="preload"]' ]
- //
- 'meta[property="twitter:card"]': {
- content: isNonEmptyString
- },
+ const images = getVideoImages( listingDetails.initialVideo )
- //
- 'meta[property="twitter:title"]': {
- content: isNonEmptyString
- },
+ // Check if the head object properties are correct
+ for ( const preload of images.preloads ) {
+ for ( const [ propertyName, checkMethod ] of Object.entries( preloadHeadChecks ) ) {
+ // Skip count property
+ if ( propertyName === 'count' ) continue
- //
- 'meta[property="twitter:description"]': {
- content: isNonEmptyString
- },
+ const value = preload[ propertyName ]
- //
- 'meta[property="twitter:url"]': {
- content: isValidHttpUrl
- },
+ t.assert( checkMethod( value ), `${ propertyName } failed. Value is '${ value }' for '${ images.imgSrc }'` )
+ }
+ }
+ }
+})
- //
- 'meta[property="twitter:image"]': {
- content: isValidImageUrl,
- },
-
- //
- 'meta[name="description"]': {
- content: isNonEmptyString
- },
-
- //
- 'meta[property="twitter:title"]': {
- content: isNonEmptyString
- },
-
- //
- 'link[rel="icon"]': {
- href: isNonEmptyString
- },
-
- //
- //
- //
- //
- //
- 'link[rel="preconnect"]': {
- href: isValidHttpUrl
- },
-}
test('Listings have valid headings', async t => {
const { listingsDetails } = t.context
@@ -196,9 +148,9 @@ test('Listings have valid headings', async t => {
let count = 1
- if ( has( checks, ['count'] ) ) {
+ if ( has( checks, 'count' ) ) {
count = checks.count
- delete checks.count
+ // delete checks.count
}
if ( count !== false ) {