-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MWPW-147289: [Nala] Refine screenshot diff tool: add IT s3 support, r…
…efine take APIS
- Loading branch information
Showing
12 changed files
with
2,138 additions
and
188 deletions.
There are no files selected for viewing
This file contains 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,98 @@ | ||
/* eslint-disable no-restricted-syntax */ | ||
const readline = require('readline'); | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
const { S3Client, ListObjectsV2Command, DeleteObjectsCommand } = require('@aws-sdk/client-s3'); | ||
|
||
const S3REGION = 'us-west-1'; | ||
const S3ENDPOINT = 'https://s3-sj3.corp.adobe.com'; | ||
|
||
async function* listObjects(s3, params) { | ||
let isTruncated = false; | ||
let token; | ||
do { | ||
const command = new ListObjectsV2Command({ ...params, ContinuationToken: token }); | ||
// eslint-disable-next-line no-await-in-loop | ||
const response = await s3.send(command); | ||
yield response.Contents; | ||
({ IsTruncated: isTruncated, NextContinuationToken: token } = response); | ||
} while (isTruncated); | ||
} | ||
|
||
function askQuestion(query) { | ||
const rl = readline.createInterface({ | ||
input: process.stdin, | ||
output: process.stdout, | ||
}); | ||
|
||
return new Promise((resolve) => { | ||
rl.question(query, (ans) => { | ||
rl.close(); | ||
resolve(ans); | ||
}); | ||
}); | ||
} | ||
|
||
async function main() { | ||
const bucket = process.argv[2]; | ||
const s3Path = process.argv[3]; | ||
|
||
if (!bucket || !s3Path) { | ||
console.log('Usage: node cleans3.js <bucket> <path>'); | ||
process.exit(1); | ||
} | ||
|
||
const s3key = process.env.s3accesskey; | ||
const s3secret = process.env.s3secretkey; | ||
|
||
const s3 = new S3Client({ | ||
region: S3REGION, | ||
endpoint: S3ENDPOINT, | ||
credentials: { | ||
accessKeyId: s3key, | ||
secretAccessKey: s3secret, | ||
}, | ||
forcePathStyle: true, | ||
}); | ||
|
||
const params = { Bucket: bucket, Prefix: s3Path, MaxKeys: 1000 }; | ||
|
||
let totalSize = 0; | ||
const toBeDeleted = { | ||
Bucket: bucket, | ||
Delete: { | ||
Objects: [], | ||
Quiet: false, | ||
}, | ||
}; | ||
|
||
for await (const contents of listObjects(s3, params)) { | ||
if (contents === undefined || contents.length === 0) { | ||
console.log('No objects to delete.'); | ||
return; // Skip to next iteration if current is empty | ||
} | ||
|
||
for (const obj of contents) { | ||
totalSize += obj.Size; | ||
console.log(`${obj.Key}, ${obj.LastModified}, ${obj.Size}`); | ||
toBeDeleted.Delete.Objects.push({ Key: obj.Key }); | ||
} | ||
} | ||
|
||
if (toBeDeleted.Delete.Objects.length > 0) { | ||
const answer = await askQuestion('Are you sure you want to delete these files? (yes/no): '); | ||
if (answer.toLowerCase() === 'yes') { | ||
const deleteCommand = new DeleteObjectsCommand(toBeDeleted); | ||
await s3.send(deleteCommand); | ||
toBeDeleted.Delete.Objects = []; | ||
console.log('Files deleted successfully.'); | ||
} else { | ||
console.log('Deletion canceled.'); | ||
} | ||
} else { | ||
console.log('No files to delete.'); | ||
} | ||
|
||
console.log(`Total Size: ${totalSize}`); | ||
} | ||
|
||
main(); |
This file contains 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,91 @@ | ||
// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions | ||
import { getComparator } from 'playwright-core/lib/utils'; | ||
import fs from 'fs'; | ||
import axios from 'axios'; | ||
import path from 'path'; | ||
|
||
const S3URL = 'https://s3-sj3.corp.adobe.com/milo'; | ||
|
||
async function downloadImage(url, localPath) { | ||
const writer = fs.createWriteStream(localPath); | ||
|
||
const res = await axios.get(url, { responseType: 'stream' }); | ||
|
||
res.data.pipe(writer); | ||
|
||
return new Promise((resolve, reject) => { | ||
writer.on('finish', resolve); | ||
writer.on('error', reject); | ||
}); | ||
} | ||
|
||
async function getSavedImages(s3Url, curEntries) { | ||
const response = await axios.get(`${s3Url}/results.json`); | ||
const preEntries = response.data; | ||
|
||
if (Object.keys(curEntries).length !== Object.keys(preEntries).length) { | ||
throw new Error(`Previous one has ${Object.keys(preEntries).length} items, | ||
but the current one has ${Object.keys(curEntries).length}`); | ||
} | ||
|
||
// eslint-disable-next-line no-restricted-syntax | ||
for (const [key, value] of Object.entries(curEntries)) { | ||
const entry = value[0]; | ||
if (!entry.b) { | ||
entry.b = entry.a; | ||
} | ||
|
||
const basename = path.basename(preEntries[key][0].a); | ||
entry.a = `${preEntries[key][0].a}`.replace('.png', '-a.png'); | ||
console.log(`Downloading ${s3Url}/${basename}`); | ||
// eslint-disable-next-line no-await-in-loop | ||
await downloadImage(`${s3Url}/${basename}`, entry.a); | ||
} | ||
} | ||
|
||
async function main() { | ||
const localPath = process.argv[2]; | ||
const s3Url = `${S3URL}/${localPath}`; | ||
|
||
if (!localPath || !s3Url) { | ||
console.log('Usage: node compare.js <localPath>'); | ||
process.exit(1); | ||
} | ||
|
||
const curEntries = JSON.parse(fs.readFileSync(`${localPath}/results.json`)); | ||
|
||
if (s3Url) { | ||
await getSavedImages(s3Url, curEntries); | ||
} | ||
|
||
const results = {}; | ||
|
||
// eslint-disable-next-line no-restricted-syntax | ||
for (const [key, value] of Object.entries(curEntries)) { | ||
const result = {}; | ||
const entry = value[0]; | ||
console.log(entry); | ||
|
||
const baseImage = fs.readFileSync(entry.a); | ||
const currImage = fs.readFileSync(entry.b); | ||
result.order = 1; | ||
result.a = entry.a; | ||
result.b = entry.b; | ||
result.urls = entry.urls; | ||
|
||
const comparator = getComparator('image/png'); | ||
const diffImage = comparator(baseImage, currImage); | ||
|
||
if (diffImage) { | ||
const diffName = `${entry.b}`.replace('.png', '-diff.png'); | ||
fs.writeFileSync(diffName, diffImage.diff); | ||
result.diff = diffName; | ||
console.info('Differences found'); | ||
} | ||
results[key] = [result]; | ||
} | ||
|
||
fs.writeFileSync(`${localPath}/results.json`, JSON.stringify(results, null, 2)); | ||
} | ||
|
||
main(); |
This file contains 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,34 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
function mergeResults(folderPath) { | ||
try { | ||
const resultsFiles = fs.readdirSync(folderPath).filter((file) => file.startsWith('results-')); | ||
let finalResults = {}; | ||
|
||
// eslint-disable-next-line no-restricted-syntax | ||
for (const file of resultsFiles) { | ||
const content = JSON.parse(fs.readFileSync(path.join(folderPath, file), 'utf-8')); | ||
finalResults = { ...finalResults, ...content }; | ||
} | ||
|
||
// Write the final merged results | ||
fs.writeFileSync(`${folderPath}/results.json`, JSON.stringify(finalResults, null, 2)); | ||
|
||
// Optionally, clean up individual files | ||
resultsFiles.forEach((file) => fs.unlinkSync(path.join(folderPath, file))); | ||
|
||
console.log('Results merged and saved successfully.'); | ||
} catch (error) { | ||
console.error('Error merging results:', error); | ||
} | ||
} | ||
|
||
// Example usage: node thisScript.js ./path/to/folder | ||
const folderPath = process.argv[2]; // Get folder path from command line argument | ||
if (!folderPath) { | ||
console.error('Please specify a folder path. e.g., screenshots/milo'); | ||
process.exit(1); | ||
} | ||
|
||
mergeResults(folderPath); |
This file contains 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
Oops, something went wrong.