-
Notifications
You must be signed in to change notification settings - Fork 2
[INT-18] send pdf snapshots to Visual #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
aga-szczepanska
merged 22 commits into
feat/INT-1/pdf-snapshots
from
feat/INT-18/send-pdf-snapshots-to-visual
Feb 27, 2025
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a886e6b
create Visual build
aga-szczepanska c26c5cc
upload and create snapshots
aga-szczepanska 51ec9ee
code cleanup
aga-szczepanska 271ebc5
add tests
aga-szczepanska 551fd6f
create api directory
aga-szczepanska 2c52227
introduce pdf converter & pdf command handler
aga-szczepanska 664f6f3
rename files
aga-szczepanska 7464d77
allow for running tests without coverage
aga-szczepanska d92117d
fix typo
aga-szczepanska 2e228ab
simplify mock in pdf-converter tests
aga-szczepanska 2173208
delete redundant casting
aga-szczepanska 430c3f6
delete redundant await
aga-szczepanska b538c7d
use toMatchSnapshot to verify logs
aga-szczepanska 55e970b
describe limitations caused by usng pdf-to-img
aga-szczepanska e1db82f
delete VisualApiParams
aga-szczepanska 967a0c7
make sure scale=1 is used
aga-szczepanska 750c03e
display build url
aga-szczepanska e4a6747
check build status after creating snapshots
aga-szczepanska 51606bb
allow for packages upgrades
aga-szczepanska 6675f29
do not deprecated fields
aga-szczepanska 337c78e
delete redundant files generated during investigating other pdf conve…
aga-szczepanska 1385f62
add PKG_VERSION to userAgent
aga-szczepanska File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { getApi, VisualConfig } from "@saucelabs/visual"; | ||
|
||
const clientVersion = "PKG_VERSION"; | ||
|
||
export const initializeVisualApi = (params: VisualConfig) => | ||
getApi(params, { | ||
userAgent: `visual-snapshots/${clientVersion}`, | ||
}); |
93 changes: 93 additions & 0 deletions
93
visual-js/visual-snapshots/src/api/visual-snapshots-api.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { BuildStatus, DiffingMethod, VisualApi } from "@saucelabs/visual"; | ||
|
||
export interface CreateVisualSnapshotsParams { | ||
branch: string; | ||
buildName: string; | ||
defaultBranch: string; | ||
project: string; | ||
customId: string; | ||
buildId: string; | ||
} | ||
|
||
export class VisualSnapshotsApi { | ||
private api: VisualApi; | ||
|
||
constructor(api: VisualApi) { | ||
this.api = api; | ||
} | ||
|
||
public async generateAndSendPdfFileSnapshots( | ||
pdfFilePages: AsyncGenerator<Buffer>, | ||
params: CreateVisualSnapshotsParams, | ||
) { | ||
const buildId = await this.createBuild(params); | ||
|
||
let pageNumber = 1; | ||
for await (const pdfPageImage of pdfFilePages) { | ||
await this.uploadImageAndCreateSnapshot( | ||
pdfPageImage, | ||
buildId, | ||
`page-${pageNumber}`, | ||
); | ||
pageNumber++; | ||
} | ||
|
||
await this.finishBuild(buildId); | ||
} | ||
|
||
private async createBuild( | ||
params: CreateVisualSnapshotsParams, | ||
): Promise<string> { | ||
const build = await this.api.createBuild({ | ||
name: params.buildName, | ||
branch: params.branch, | ||
defaultBranch: params.defaultBranch, | ||
project: params.project, | ||
customId: params.customId, | ||
}); | ||
console.info(`Build ${build.id} created: ${build.url}`); | ||
return build.id; | ||
} | ||
|
||
private async uploadImageAndCreateSnapshot( | ||
snapshot: Buffer, | ||
buildId: string, | ||
snapshotName: string, | ||
) { | ||
const uploadId = await this.api.uploadSnapshot({ | ||
buildId, | ||
image: { data: snapshot }, | ||
}); | ||
|
||
console.info(`Uploaded image to build ${buildId}: upload id=${uploadId}.`); | ||
|
||
await this.api.createSnapshot({ | ||
buildId, | ||
uploadId, | ||
name: snapshotName, | ||
diffingMethod: DiffingMethod.Balanced, | ||
}); | ||
|
||
console.info(`Created a snapshot ${snapshotName} for build ${buildId}.`); | ||
} | ||
|
||
private async finishBuild(buildId: string) { | ||
await this.api.finishBuild({ | ||
uuid: buildId, | ||
}); | ||
console.info(`Build ${buildId} finished.`); | ||
|
||
const buildStatus = (await this.api.buildStatus(buildId))!; | ||
if ( | ||
[BuildStatus.Running, BuildStatus.Queued].includes(buildStatus.status) | ||
paweltomaszewskisaucelabs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) { | ||
console.info( | ||
`Build ${buildId} finished but snapshots haven't been compared yet. Check the build status in a few moments.`, | ||
); | ||
} else { | ||
console.info( | ||
`Build ${buildId} finished (status=${buildStatus.status}, unapprovedCount=${buildStatus.unapprovedCount}, errorCount=${buildStatus.errorCount}).`, | ||
); | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { pdf } from "pdf-to-img"; | ||
|
||
export class PdfConverter { | ||
public async *convertPagesToImages( | ||
pdfFilePath: string, | ||
): AsyncGenerator<Buffer> { | ||
for await (const pdfPageImage of await pdf(pdfFilePath, { scale: 1 })) { | ||
yield pdfPageImage; | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { | ||
CreateVisualSnapshotsParams, | ||
VisualSnapshotsApi, | ||
} from "../api/visual-snapshots-api.js"; | ||
import { initializeVisualApi } from "../api/visual-client.js"; | ||
import { PdfConverter } from "./pdf-converter.js"; | ||
import { VisualConfig } from "@saucelabs/visual"; | ||
|
||
export interface PdfCommandParams | ||
aga-szczepanska marked this conversation as resolved.
Show resolved
Hide resolved
|
||
extends VisualConfig, | ||
CreateVisualSnapshotsParams {} | ||
|
||
export class PdfCommandHandler { | ||
public async handle(pdfFilePath: string, params: PdfCommandParams) { | ||
const visualApi = initializeVisualApi(params); | ||
const visualSnapshots = new VisualSnapshotsApi(visualApi); | ||
const pdfConverter = new PdfConverter(); | ||
|
||
const pdfPageImages = pdfConverter.convertPagesToImages(pdfFilePath); | ||
await visualSnapshots.generateAndSendPdfFileSnapshots( | ||
pdfPageImages, | ||
params, | ||
); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
visual-js/visual-snapshots/test/api/__snapshots__/visual-api.spec.ts.snap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`VisualSnapshots generateAndSendPdfFileSnapshots with params difffing finished 1`] = ` | ||
[ | ||
[ | ||
"Build build-id created: http://build-url/build-id", | ||
], | ||
[ | ||
"Uploaded image to build build-id: upload id=upload-id-0.", | ||
], | ||
[ | ||
"Created a snapshot page-1 for build build-id.", | ||
], | ||
[ | ||
"Uploaded image to build build-id: upload id=upload-id-1.", | ||
], | ||
[ | ||
"Created a snapshot page-2 for build build-id.", | ||
], | ||
[ | ||
"Build build-id finished.", | ||
], | ||
[ | ||
"Build build-id finished (status=APPROVED, unapprovedCount=0, errorCount=0).", | ||
], | ||
] | ||
`; | ||
|
||
exports[`VisualSnapshots generateAndSendPdfFileSnapshots with params difffing unfinished 1`] = ` | ||
[ | ||
[ | ||
"Build build-id created: http://build-url/build-id", | ||
], | ||
[ | ||
"Uploaded image to build build-id: upload id=upload-id-0.", | ||
], | ||
[ | ||
"Created a snapshot page-1 for build build-id.", | ||
], | ||
[ | ||
"Uploaded image to build build-id: upload id=upload-id-1.", | ||
], | ||
[ | ||
"Created a snapshot page-2 for build build-id.", | ||
], | ||
[ | ||
"Build build-id finished.", | ||
], | ||
[ | ||
"Build build-id finished but snapshots haven't been compared yet. Check the build status in a few moments.", | ||
], | ||
] | ||
`; | ||
|
||
exports[`VisualSnapshots generateAndSendPdfFileSnapshots without params 1`] = ` | ||
[ | ||
[ | ||
"Build build-id created: http://build-url/build-id", | ||
], | ||
[ | ||
"Uploaded image to build build-id: upload id=upload-id-0.", | ||
], | ||
[ | ||
"Created a snapshot page-1 for build build-id.", | ||
], | ||
[ | ||
"Uploaded image to build build-id: upload id=upload-id-1.", | ||
], | ||
[ | ||
"Created a snapshot page-2 for build build-id.", | ||
], | ||
[ | ||
"Build build-id finished.", | ||
], | ||
[ | ||
"Build build-id finished (status=UNAPPROVED, unapprovedCount=2, errorCount=0).", | ||
], | ||
] | ||
`; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.