Skip to content

Commit

Permalink
fix: Add Percy specific CSS to root resource after asset discovery (#352
Browse files Browse the repository at this point in the history
)

* fix: Add debug logs to percy specific CSS

* fix: Add Percy specific CSS to root resource after asset discovery

Before, it's possible the asset discovery resource saves the CSS as a different
content type (for example, if their server just serves the root index for this
request, we would get DOM instead of CSS)

* fix: SHA root resource after we modify it for percy css
  • Loading branch information
Robdel12 authored Sep 24, 2019
1 parent 8abb589 commit 5984a65
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
22 changes: 13 additions & 9 deletions src/services/agent-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,6 @@ export class AgentService {
}

let domSnapshot = request.body.domSnapshot
const percyCSSFileName = `percy-specific.${Date.now()}.css` as string

// Inject the link to the percy specific css if the option is passed
if (snapshotOptions.percyCSS) {
const cssLink = `<link data-percy-specific-css rel="stylesheet" href="/${percyCSSFileName}" />`
domSnapshot = domSnapshot.replace(/<\/body>/i, cssLink + '$&')
}

if (domSnapshot.length > Constants.MAX_FILE_SIZE_BYTES) {
logger.info(`snapshot skipped[max_file_size_exceeded]: '${request.body.name}'`)
Expand All @@ -127,10 +120,21 @@ export class AgentService {
snapshotLogger,
)

const percyCSSFileName = `percy-specific.${Date.now()}.css` as string

// Inject the link to the percy specific css if the option is passed
// This must be done _AFTER_ asset discovery, or you risk their server
// serving a response for this CSS we're injecting into the DOM
if (snapshotOptions.percyCSS) {
const cssLink = `<link data-percy-specific-css rel="stylesheet" href="/${percyCSSFileName}" />`
domSnapshot = domSnapshot.replace(/<\/body>/i, cssLink + '$&')
}

resources = resources.concat(
this.snapshotService.buildLogResource(snapshotLog),
this.snapshotService.buildRootResource(request.body.url, domSnapshot),
// @ts-ignore we won't write anything if css is not is passed
this.snapshotService.buildPercyCSSResource(percyCSSFileName, snapshotOptions.percyCSS),
this.snapshotService.buildPercyCSSResource(percyCSSFileName, snapshotOptions.percyCSS, snapshotLogger),
this.snapshotService.buildLogResource(snapshotLog),
)

const snapshotCreation = this.snapshotService.create(
Expand Down
26 changes: 15 additions & 11 deletions src/services/snapshot-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,27 @@ export default class SnapshotService extends PercyClientService {
this.assetDiscoveryService = new AssetDiscoveryService(buildId, configuration)
}

async buildResources(
buildResources(
rootResourceUrl: string,
domSnapshot = '',
options: SnapshotOptions,
logger: any,
): Promise<any[]> {
const rootResource = this.percyClient.makeResource({
resourceUrl: rootResourceUrl,
content: domSnapshot,
isRoot: true,
mimetype: 'text/html',
})

const discoveredResources = await this.assetDiscoveryService.discoverResources(
return this.assetDiscoveryService.discoverResources(
rootResourceUrl,
domSnapshot,
options,
logger,
)
}

return [rootResource].concat(discoveredResources)
buildRootResource(rootResourceUrl: string, domSnapshot = ''): Promise<any[]> {
return this.percyClient.makeResource({
resourceUrl: rootResourceUrl,
content: domSnapshot,
isRoot: true,
mimetype: 'text/html',
})
}

buildLogResource(logFilePath: string) {
Expand All @@ -65,15 +65,19 @@ export default class SnapshotService extends PercyClientService {
})
}

buildPercyCSSResource(fileName: string, css: string) {
buildPercyCSSResource(fileName: string, css: string, logger: any) {
if (!css) { return [] }
logger.debug(`Creating Percy Specific file: ${fileName}. CSS string: ${css}`)

const buffer = Buffer.from(css, 'utf8')
const sha = crypto.createHash('sha256').update(buffer).digest('hex')
const localPath = path.join(os.tmpdir(), sha)

// write the SHA file if it doesn't exist
if (!fs.existsSync(localPath)) {
fs.writeFileSync(localPath, buffer, 'utf8')
} else {
logger.debug(`Skipping writing Percy specific file: ${fileName}.`)
}

return this.percyClient.makeResource({
Expand Down

0 comments on commit 5984a65

Please sign in to comment.