From cf61dd7c8b37089aaa511cc5432f4db2679fa8a4 Mon Sep 17 00:00:00 2001 From: Universe Date: Fri, 16 Jun 2023 01:09:45 +0900 Subject: [PATCH 01/16] update codetest/server - serve local reports --- testing/server/bin.ts | 24 ++++++++++ testing/server/package.json | 11 +++-- testing/server/server.ts | 56 +++++++++++++++++------ testing/server/tsconfig.json | 14 +++--- testing/server/tsup.config.ts | 8 ++++ yarn.lock | 86 +++++++++++++++++++++++++++-------- 6 files changed, 157 insertions(+), 42 deletions(-) create mode 100644 testing/server/bin.ts create mode 100644 testing/server/tsup.config.ts diff --git a/testing/server/bin.ts b/testing/server/bin.ts new file mode 100644 index 00000000..ec0d171a --- /dev/null +++ b/testing/server/bin.ts @@ -0,0 +1,24 @@ +// cli for booting up testing local server + +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { start, ServerOptions, defaultOptions } from "./server"; + +const argv = yargs(hideBin(process.argv)) + .option("port", { + alias: "p", + description: "The port to bind the server to", + type: "number", + default: defaultOptions.port, + }) + .option("reports", { + description: "The path to the folder with the files", + type: "string", + demandOption: true, + }) + .help() + .alias("help", "h").argv as ServerOptions; + +if (require.main === module) { + start({ port: argv.port, reports: argv.reports }); +} diff --git a/testing/server/package.json b/testing/server/package.json index cb7d3290..188e4b68 100644 --- a/testing/server/package.json +++ b/testing/server/package.json @@ -2,19 +2,24 @@ "name": "@codetest/server", "version": "0.0.0", "private": true, + "bin": { + "codetest-server": "dist/bin.js" + }, "scripts": { - "dev": "ts-node server.ts", - "start": "node dist/server.js", + "dev": "ts-node bin.ts", + "start": "node dist/bin.js", "build": "tsup", "test": "jest" }, "dependencies": { "express": "^4.18.2", - "python-shell": "^5.0.0" + "python-shell": "^5.0.0", + "yargs": "^17.2.1" }, "devDependencies": { "@types/express": "^4.17.17", "@types/node": "^20.2.5", + "@types/yargs": "^17.0.24", "jest": "^29.5.0", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", diff --git a/testing/server/server.ts b/testing/server/server.ts index 797d8469..cb9dcf1c 100644 --- a/testing/server/server.ts +++ b/testing/server/server.ts @@ -1,26 +1,52 @@ import express from "express"; import path from "path"; -import { ssim } from "@codetest/diffview"; import router_reports from "./reports"; import router_screenshots from "./screenshots"; -const app = express(); +export interface ServerOptions { + /** + * port number + * @default 6627 + */ + port?: number; + /** + * reports artifect path + */ + reports: string; +} -app.get("/", (req, res) => { - res.send("service is running"); -}); +export const defaultOptions: ServerOptions = { + port: 6627, + reports: path.join(__dirname, "..", "report", ".coverage"), +}; -app.use("/reports", router_reports); +export function start({ + port = defaultOptions.port, + reports = defaultOptions.reports, +}: ServerOptions) { + const app = express(); -app.use("/screenshots", router_screenshots); + // ping + app.get("/", (req, res) => { + res.send("service is running"); + }); -app.listen(3000, () => { - console.log("listening on port 3000"); -}); + // reports + app.use("/reports", router_reports); + app.use("/public/reports", express.static(reports)); -const demodir = path.join(__dirname, "../samples/demo"); -const a = path.join(demodir, "a.png"); -const b = path.join(demodir, "b.png"); -const o = demodir; + // take screenshots + app.use("/screenshots", router_screenshots); -ssim(a, b, o).then(console.log); + app.listen(port, () => { + console.log(`listening on port ${port} => http://localhost:${port}`); + console.log({ + port, + reports, + }); + }); +} + +if (require.main === module) { + start(defaultOptions); +} diff --git a/testing/server/tsconfig.json b/testing/server/tsconfig.json index 1e2dce1f..ce6b0dc2 100644 --- a/testing/server/tsconfig.json +++ b/testing/server/tsconfig.json @@ -1,12 +1,14 @@ { "compilerOptions": { + "target": "es2020", "module": "commonjs", - "esModuleInterop": true, - "target": "es2017", - "noImplicitAny": false, + "lib": ["es2020", "dom"], + "outDir": "./dist", + "baseUrl": ".", + "strict": false, "moduleResolution": "node", - "sourceMap": true, - "outDir": "dist", - "baseUrl": "." + "esModuleInterop": true, + "resolveJsonModule": true, + "skipLibCheck": true } } diff --git a/testing/server/tsup.config.ts b/testing/server/tsup.config.ts new file mode 100644 index 00000000..1c8254f9 --- /dev/null +++ b/testing/server/tsup.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["server.ts", "bin.ts"], + splitting: false, + sourcemap: true, + clean: true, +}); diff --git a/yarn.lock b/yarn.lock index 91667076..f6db7f37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1479,10 +1479,10 @@ resolved "https://registry.npmjs.org/@design-sdk/figma-auth-store/-/figma-auth-store-0.0.43.tgz" integrity sha512-5VF1EijfZwzOMq+r4ipQ0aDRk/JSUHOjg9cI7oaD+K+sw2YIjgxSBE05/tvncZhOpmFvDHSHTISYJfUsEWfSUQ== -"@design-sdk/figma-core@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@design-sdk/figma-core/-/figma-core-0.0.25.tgz#7fa28cc7d6e45cd713c5f268d42e4dd4f2b41590" - integrity sha512-6OF7eUbDOlR4/BFtd2FRyDvvUf777OGNbVbNScUOv3Fk/kUXBzMTXX6ZdoRlTx887v/vo3+Lh0D31SG1sm80aA== +"@design-sdk/figma-core@^0.0.43": + version "0.0.43" + resolved "https://registry.yarnpkg.com/@design-sdk/figma-core/-/figma-core-0.0.43.tgz#0d19d014daf398ed39046bfd4e7f3d2b78842943" + integrity sha512-7WQ29f4hUOxu4Mu8ZyqbBI5F4DsRJbIjGIcZAUmn7O9/SRR00upTYrl2hdlEnKdE0ImHTYqfISgxjkoYEQgZaQ== "@design-sdk/figma-node-conversion@^0.0.43": version "0.0.43" @@ -1505,13 +1505,13 @@ "@design-sdk/figma-node" "^0.0.43" "@design-sdk/figma-types" "^0.0.43" -"@design-sdk/figma-node@0.0.25", "@design-sdk/figma-node@^0.0.43": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@design-sdk/figma-node/-/figma-node-0.0.25.tgz#c95484cc4b003667ae93e95fa3b585b9fa0b740a" - integrity sha512-GCA5cGDXhvGUQddmSIZgPMhH0eGip9S0yDSQiys1XiKnXsB/CM8/5C+JVosHR1WFMHSlJfU+ytA4IH2yhfysUQ== +"@design-sdk/figma-node@^0.0.43": + version "0.0.43" + resolved "https://registry.yarnpkg.com/@design-sdk/figma-node/-/figma-node-0.0.43.tgz#5d468ae73e2b07a787d4e6447cdde7efb4f2ea43" + integrity sha512-Wo3jNL4S8NjqbwZZG4eXe2ut/HVM/vPGaEFoEa8MIJyTslwS+sobiU4TW2qDUYNVZW/L7fxYdHO+sBDQOx0TWw== dependencies: - "@design-sdk/figma-core" "^0.0.25" - "@design-sdk/figma-utils" "^0.0.25" + "@design-sdk/figma-core" "^0.0.43" + "@design-sdk/figma-utils" "^0.0.43" "@reflect-ui/font-utils" "^0.0.1" "@design-sdk/figma-remote-api@^0.0.43": @@ -1555,11 +1555,6 @@ resolved "https://registry.yarnpkg.com/@design-sdk/figma-url/-/figma-url-0.0.46.tgz#8cf8eecbb80685480822734bfa871af6e5fa0daa" integrity sha512-9d8Og45cPxRe3Oh8wzWHhFrxZYfaoBdfP/J0OfYs2yTK7XY/vhz1GGf78aBjGdBdmaShHwfI8RHIhhV03nYKkg== -"@design-sdk/figma-utils@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@design-sdk/figma-utils/-/figma-utils-0.0.25.tgz#7b7f6632fd8689ef713b27b34a61257accc2052e" - integrity sha512-HarFMa14L9zqg8rhLaCTXhTKFd6tlBno1mnSc/vl8ZVilmdq32OFFlmqS4MjyvrTfyAvbwlEMAhxV1SUQhFhRg== - "@design-sdk/figma-utils@^0.0.43": version "0.0.43" resolved "https://registry.npmjs.org/@design-sdk/figma-utils/-/figma-utils-0.0.43.tgz" @@ -6705,7 +6700,19 @@ resolved "https://registry.npmjs.org/@reflect-ui/cg/-/cg-0.0.5.tgz" integrity sha512-rqqaumLDgk9dGtPgkYy9h5PLlNv8ZVEz/+ktOcJpJE6v9fAQOSH1Wh5WAehpiZTQtKe944GzrFMsb/g8pTabWg== -"@reflect-ui/core@0.0.2-rc.7", "@reflect-ui/core@0.0.5", "@reflect-ui/core@0.0.9", "@reflect-ui/core@^0.0.5", "@reflect-ui/core@^0.0.9": +"@reflect-ui/core@0.0.2-rc.7": + version "0.0.2-rc.7" + resolved "https://registry.yarnpkg.com/@reflect-ui/core/-/core-0.0.2-rc.7.tgz#9d531f5a0b9caab31e7563020044b753700e2bbc" + integrity sha512-EqF4SRU57bfa5DOPET1rv5lROFyMVHLv1xTEIlN6N2gDpXt71QceImWfQp3z3Khqnb4R/p9OhNK6DXGUpozWKw== + +"@reflect-ui/core@0.0.5", "@reflect-ui/core@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@reflect-ui/core/-/core-0.0.5.tgz#f50ae00e64300c4b698ab5c5374c6ac3bb5de873" + integrity sha512-lA6AYHCF8aSyOvGXbJZcmlB5ccxCaznhxvD8Hg1UjVdhcbLhMWDbzoYqbrkqh+R4im3KnYw5n6pWSSdoWioYhA== + dependencies: + "@reflect-ui/uiutils" "^0.1.2-1" + +"@reflect-ui/core@^0.0.9": version "0.0.9" resolved "https://registry.yarnpkg.com/@reflect-ui/core/-/core-0.0.9.tgz#7283a2a3a1edde16282559d11f02e23d3bceda36" integrity sha512-MNJq+Pc45qZ0IvTYuvzCW2nxupVRfMtmin9vepABo2h1sTKdAmCK2kPfVLea6TNiF1baJDeQg7IyAN45JMuFdA== @@ -9197,7 +9204,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@18.0.24", "@types/react@^17", "@types/react@^18.0.24", "@types/react@^18.0.25": +"@types/react@*", "@types/react@^18.0.24": version "18.0.24" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.24.tgz#2f79ed5b27f08d05107aab45c17919754cc44c20" integrity sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q== @@ -9206,6 +9213,24 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^17": + version "17.0.62" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.62.tgz#2efe8ddf8533500ec44b1334dd1a97caa2f860e3" + integrity sha512-eANCyz9DG8p/Vdhr0ZKST8JV12PhH2ACCDYlFw6DIO+D+ca+uP4jtEDEpVqXZrh/uZdXQGwk7whJa3ah5DtyLw== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/react@^18.0.25": + version "18.2.12" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.12.tgz#95d584338610b78bb9ba0415e3180fb03debdf97" + integrity sha512-ndmBMLCgn38v3SntMeoJaIrO6tGHYKMEBohCUmw8HoLLQdRMOIGXfeYaBTLe2lsFaSB3MOK1VXscYFnmLtTSmw== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/resemblejs@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@types/resemblejs/-/resemblejs-4.1.0.tgz#1c150e0de4117b29f9d5d5231489edc7cef8263e" @@ -9331,6 +9356,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^17.0.24": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^17.0.8": version "17.0.15" resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz" @@ -12425,11 +12457,16 @@ cssesc@^3.0.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@3.1.0, csstype@^3.0.10, csstype@^3.0.2, csstype@^3.0.4, csstype@^3.0.8, csstype@^3.1.1: +csstype@^3.0.10, csstype@^3.0.2, csstype@^3.0.4, csstype@^3.0.8: version "3.1.0" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== +csstype@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + cuid@^2.1.8: version "2.1.8" resolved "https://registry.npmjs.org/cuid/-/cuid-2.1.8.tgz" @@ -25712,6 +25749,19 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.2.1: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yargs@^17.3.1: version "17.6.2" resolved "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz" From d8baff99f5b67ea4a996ed28416bce9bb7723860 Mon Sep 17 00:00:00 2001 From: Universe Date: Sat, 17 Jun 2023 04:32:38 +0900 Subject: [PATCH 02/16] reports server --- testing/server/package.json | 1 + testing/server/reports/index.ts | 91 +++++++++++++++++++++++++++++++-- testing/server/server.ts | 9 ++++ 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/testing/server/package.json b/testing/server/package.json index 188e4b68..4b3a22d1 100644 --- a/testing/server/package.json +++ b/testing/server/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "express": "^4.18.2", + "glob": "^10.2.7", "python-shell": "^5.0.0", "yargs": "^17.2.1" }, diff --git a/testing/server/reports/index.ts b/testing/server/reports/index.ts index d560cb95..2c7b2af3 100644 --- a/testing/server/reports/index.ts +++ b/testing/server/reports/index.ts @@ -1,18 +1,101 @@ import express from "express"; +import fs from "fs/promises"; +import path from "path"; +import { globSync } from "glob"; const router = express.Router(); -router.get("/", (req, res) => { +router.get("/", async (req, res) => { + const reportsdir = req.app.get("reports"); // list all available report coverage + + // list all directories under reportsdir + const items = await fs.readdir(reportsdir); + + // filter items with valid report coverage + // - must be a directory + // - must contain at least one suv directory + const files = await Promise.all( + items.map(async (item) => { + const p = path.join(reportsdir, item); + const stat = await fs.stat(p); + if (!stat.isDirectory()) { + return null; + } + + const nodes = await fs.readdir(p); + if (nodes.length === 0) { + return null; + } + + return item; + }) + ); + + res.json({ + files: files.filter(Boolean), + }); }); -router.get("/:fileid", (req, res) => { +router.get("/:file", async (req, res) => { + const server = res.locals.server; + const reportsdir = req.app.get("reports"); + const file = req.params.file; + // list reports under fileid - // + const p = path.join(reportsdir, file); + + // each node directory (should be a directory) must contain report.json + // use glob to find all report.json, list the parent directory (the node directory) + const data = globSync(`${p}/**/report.json`).reduce((acc, cur) => { + const dir = path.dirname(cur); + const nodeid = path.basename(path.dirname(cur)); + return { + ...acc, + [nodeid]: { + report: server + `/public/reports/${file}/${nodeid}/report.json`, + a: server + `/public/reports/${file}/${nodeid}/a.png`, + b: server + `/public/reports/${file}/${nodeid}/b.png`, + diff: server + `/public/reports/${file}/${nodeid}/diff.png`, + }, + }; + }, {}); + + res.json(data); }); -router.get("/:fileid/:node", (req, res) => { +router.get("/:file/:node", async (req, res) => { + const server = res.locals.server; + const reportsdir = req.app.get("reports"); + const file = req.params.file; + const nodeid = req.params.node; // + const p = path.join(reportsdir, file, nodeid); + + // check if directory exists + // if not, return 404 + const stat = await fs.stat(p); + if (!stat.isDirectory()) { + res.status(404).send("not found"); + return; + } + + // check if valid report.json exists + // if not, return 404 + const report = path.join(p, "report.json"); + try { + await fs.access(report); + } catch (e) { + res.status(404).send("not found"); + return; + } + + res.json({ + report: server + `/public/reports/${file}/${nodeid}/report.json`, + a: server + `/public/reports/${file}/${nodeid}/a.png`, + b: server + `/public/reports/${file}/${nodeid}/b.png`, + diff: server + `/public/reports/${file}/${nodeid}/diff.png`, + }); }); export default router; diff --git a/testing/server/server.ts b/testing/server/server.ts index cb9dcf1c..80b01bcd 100644 --- a/testing/server/server.ts +++ b/testing/server/server.ts @@ -26,6 +26,15 @@ export function start({ }: ServerOptions) { const app = express(); + // set env + app.set("reports", reports); + + // set baseurl middleware + app.use((req, res, next) => { + res.locals.server = req.protocol + "://" + req.get("host"); + next(); + }); + // ping app.get("/", (req, res) => { res.send("service is running"); From e998fd92eb47f67c49958d4af86e7d8d2556d686 Mon Sep 17 00:00:00 2001 From: Universe Date: Sat, 17 Jun 2023 04:32:54 +0900 Subject: [PATCH 03/16] reports server editor api client --- testing/testing-editor-client/client.ts | 27 +++++++++++++++++++++++++ testing/testing-editor-client/index.ts | 16 ++------------- testing/testing-editor-client/types.ts | 22 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 testing/testing-editor-client/client.ts create mode 100644 testing/testing-editor-client/types.ts diff --git a/testing/testing-editor-client/client.ts b/testing/testing-editor-client/client.ts new file mode 100644 index 00000000..b264262d --- /dev/null +++ b/testing/testing-editor-client/client.ts @@ -0,0 +1,27 @@ +import Axios, { AxiosPromise } from "axios"; +import { + NodeReportParams, + FileReportsParams, + FileReportsResponse, + NodeReportResponse, + AllReportsReponse, +} from "./types"; + +export interface ClientInterface { + reports: () => AxiosPromise; + file: (params: FileReportsParams) => AxiosPromise; + node: (params: NodeReportParams) => AxiosPromise; +} + +export const Client = ({ baseURL }: { baseURL: string }): ClientInterface => { + const client = Axios.create({ + baseURL, + }); + + return { + reports: async () => client.get(`/reports`), + file: async ({ file }: FileReportsParams) => client.get(`/reports/${file}`), + node: async ({ file, node }: NodeReportParams) => + client.get(`/reports/${file}/${node}`), + }; +}; diff --git a/testing/testing-editor-client/index.ts b/testing/testing-editor-client/index.ts index 407bd9c1..d2ec2302 100644 --- a/testing/testing-editor-client/index.ts +++ b/testing/testing-editor-client/index.ts @@ -1,14 +1,2 @@ -import Axios from "axios"; - -const axios = Axios.create({ - baseURL: "http://localhost:3000", -}); - -function reports() { - // -} - -function screenshot_htmlcss() { - axios.post("/screenshots/htmlcss", {}); - // -} +export * from "./client"; +export * from "./types"; diff --git a/testing/testing-editor-client/types.ts b/testing/testing-editor-client/types.ts new file mode 100644 index 00000000..9d274f5c --- /dev/null +++ b/testing/testing-editor-client/types.ts @@ -0,0 +1,22 @@ +export interface FileReportsParams { + file: string; +} + +export interface NodeReportParams { + file: string; + node: string; +} + +export type NodeReportCoverage = { + a: string; + b: string; + diff: string; + report: string; +}; + +export type FileReportsResponse = { [key: string]: NodeReportCoverage }; +export type NodeReportResponse = NodeReportCoverage; + +export type AllReportsReponse = { + files: string[]; +}; From 2439382293bc86bde05b07ff7af53cc6d6cf02ca Mon Sep 17 00:00:00 2001 From: Universe Date: Sat, 17 Jun 2023 04:33:13 +0900 Subject: [PATCH 04/16] qa reports viewer page --- editor/pages/qa/files/[key]/index.tsx | 80 ++++++++++++++++++++++++--- editor/pages/qa/files/index.tsx | 56 +++++++++++++++++++ 2 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 editor/pages/qa/files/index.tsx diff --git a/editor/pages/qa/files/[key]/index.tsx b/editor/pages/qa/files/[key]/index.tsx index f4d86b6d..d006b524 100644 --- a/editor/pages/qa/files/[key]/index.tsx +++ b/editor/pages/qa/files/[key]/index.tsx @@ -1,17 +1,83 @@ +import React, { useEffect } from "react"; import Head from "next/head"; -import React from "react"; +import { InferGetServerSidePropsType } from "next"; +import styled from "@emotion/styled"; +import { Client, NodeReportCoverage } from "@codetest/editor-client"; -export default function QAEditor() { +type P = InferGetServerSidePropsType; + +export default function QAEditor({ key, data }: P) { return ( <> - QA + QA - {key} {/* */} -
- {/* */} - {/* */} -
+
+ {/* +
{JSON.stringify(data, null, 2)}
+
*/} +
+ {Object.keys(data).map((k) => { + const record: NodeReportCoverage = data[k]; + return ( +
+

{k}

+ A + B + B +
+ ); + })} +
+
); } + +const Main = styled.main` + /* */ + .frames { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + flex-wrap: wrap; + } + + .item { + display: flex; + flex-direction: column; + + width: 400px; + height: 400px; + + img { + width: 100%; + height: auto; + } + } +`; + +export async function getServerSideProps(context: any) { + const key = context.params.key; + + const client = Client({ + baseURL: "http://localhost:6627", + }); + + try { + const { data } = await client.file({ file: key }); + + return { + props: { + key, + data, + }, + }; + } catch (e) { + return { + notFound: true, + }; + } +} diff --git a/editor/pages/qa/files/index.tsx b/editor/pages/qa/files/index.tsx new file mode 100644 index 00000000..852247cd --- /dev/null +++ b/editor/pages/qa/files/index.tsx @@ -0,0 +1,56 @@ +import Head from "next/head"; +import React from "react"; +import { Client } from "@codetest/editor-client"; +import Link from "next/link"; + +export default function QAFilesPage({ files }) { + return ( + <> + + QA - Files + +
+

QA - Files

+
+ {files.map((file) => ( + + {file} + + ))} +
+
+ + ); +} + +export async function getServerSideProps(context: any) { + const client = Client({ + baseURL: "http://localhost:6627", + }); + + try { + const { data } = await client.reports(); + + return { + props: { + files: data.files, + }, + }; + } catch (e) { + return { + notFound: true, + }; + } +} From 00ec85ef11b2d15d6b80fc03ca93af06f58152fe Mon Sep 17 00:00:00 2001 From: Universe Date: Sat, 17 Jun 2023 04:33:16 +0900 Subject: [PATCH 05/16] config --- editor/next.config.js | 3 + yarn.lock | 211 ++++++++++++++++++++++++++++++++---------- 2 files changed, 166 insertions(+), 48 deletions(-) diff --git a/editor/next.config.js b/editor/next.config.js index 98e42336..945838b7 100644 --- a/editor/next.config.js +++ b/editor/next.config.js @@ -74,6 +74,9 @@ const packages = [ "@web-builder/styles", // endregion web builders // ----------------------------- + + // region codetest + "@codetest/editor-client", ]; const withPlugins = require("next-compose-plugins"); diff --git a/yarn.lock b/yarn.lock index f6db7f37..7f8eaa55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1479,10 +1479,10 @@ resolved "https://registry.npmjs.org/@design-sdk/figma-auth-store/-/figma-auth-store-0.0.43.tgz" integrity sha512-5VF1EijfZwzOMq+r4ipQ0aDRk/JSUHOjg9cI7oaD+K+sw2YIjgxSBE05/tvncZhOpmFvDHSHTISYJfUsEWfSUQ== -"@design-sdk/figma-core@^0.0.43": - version "0.0.43" - resolved "https://registry.yarnpkg.com/@design-sdk/figma-core/-/figma-core-0.0.43.tgz#0d19d014daf398ed39046bfd4e7f3d2b78842943" - integrity sha512-7WQ29f4hUOxu4Mu8ZyqbBI5F4DsRJbIjGIcZAUmn7O9/SRR00upTYrl2hdlEnKdE0ImHTYqfISgxjkoYEQgZaQ== +"@design-sdk/figma-core@^0.0.25": + version "0.0.25" + resolved "https://registry.yarnpkg.com/@design-sdk/figma-core/-/figma-core-0.0.25.tgz#7fa28cc7d6e45cd713c5f268d42e4dd4f2b41590" + integrity sha512-6OF7eUbDOlR4/BFtd2FRyDvvUf777OGNbVbNScUOv3Fk/kUXBzMTXX6ZdoRlTx887v/vo3+Lh0D31SG1sm80aA== "@design-sdk/figma-node-conversion@^0.0.43": version "0.0.43" @@ -1505,13 +1505,13 @@ "@design-sdk/figma-node" "^0.0.43" "@design-sdk/figma-types" "^0.0.43" -"@design-sdk/figma-node@^0.0.43": - version "0.0.43" - resolved "https://registry.yarnpkg.com/@design-sdk/figma-node/-/figma-node-0.0.43.tgz#5d468ae73e2b07a787d4e6447cdde7efb4f2ea43" - integrity sha512-Wo3jNL4S8NjqbwZZG4eXe2ut/HVM/vPGaEFoEa8MIJyTslwS+sobiU4TW2qDUYNVZW/L7fxYdHO+sBDQOx0TWw== +"@design-sdk/figma-node@0.0.25", "@design-sdk/figma-node@^0.0.43": + version "0.0.25" + resolved "https://registry.yarnpkg.com/@design-sdk/figma-node/-/figma-node-0.0.25.tgz#c95484cc4b003667ae93e95fa3b585b9fa0b740a" + integrity sha512-GCA5cGDXhvGUQddmSIZgPMhH0eGip9S0yDSQiys1XiKnXsB/CM8/5C+JVosHR1WFMHSlJfU+ytA4IH2yhfysUQ== dependencies: - "@design-sdk/figma-core" "^0.0.43" - "@design-sdk/figma-utils" "^0.0.43" + "@design-sdk/figma-core" "^0.0.25" + "@design-sdk/figma-utils" "^0.0.25" "@reflect-ui/font-utils" "^0.0.1" "@design-sdk/figma-remote-api@^0.0.43": @@ -1555,6 +1555,11 @@ resolved "https://registry.yarnpkg.com/@design-sdk/figma-url/-/figma-url-0.0.46.tgz#8cf8eecbb80685480822734bfa871af6e5fa0daa" integrity sha512-9d8Og45cPxRe3Oh8wzWHhFrxZYfaoBdfP/J0OfYs2yTK7XY/vhz1GGf78aBjGdBdmaShHwfI8RHIhhV03nYKkg== +"@design-sdk/figma-utils@^0.0.25": + version "0.0.25" + resolved "https://registry.yarnpkg.com/@design-sdk/figma-utils/-/figma-utils-0.0.25.tgz#7b7f6632fd8689ef713b27b34a61257accc2052e" + integrity sha512-HarFMa14L9zqg8rhLaCTXhTKFd6tlBno1mnSc/vl8ZVilmdq32OFFlmqS4MjyvrTfyAvbwlEMAhxV1SUQhFhRg== + "@design-sdk/figma-utils@^0.0.43": version "0.0.43" resolved "https://registry.npmjs.org/@design-sdk/figma-utils/-/figma-utils-0.0.43.tgz" @@ -2877,6 +2882,18 @@ resolved "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@isaacs/string-locale-compare@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz" @@ -4742,6 +4759,11 @@ "@otplib/plugin-crypto" "^12.0.1" "@otplib/plugin-thirty-two" "^12.0.1" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": version "0.5.10" resolved "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz" @@ -6700,19 +6722,7 @@ resolved "https://registry.npmjs.org/@reflect-ui/cg/-/cg-0.0.5.tgz" integrity sha512-rqqaumLDgk9dGtPgkYy9h5PLlNv8ZVEz/+ktOcJpJE6v9fAQOSH1Wh5WAehpiZTQtKe944GzrFMsb/g8pTabWg== -"@reflect-ui/core@0.0.2-rc.7": - version "0.0.2-rc.7" - resolved "https://registry.yarnpkg.com/@reflect-ui/core/-/core-0.0.2-rc.7.tgz#9d531f5a0b9caab31e7563020044b753700e2bbc" - integrity sha512-EqF4SRU57bfa5DOPET1rv5lROFyMVHLv1xTEIlN6N2gDpXt71QceImWfQp3z3Khqnb4R/p9OhNK6DXGUpozWKw== - -"@reflect-ui/core@0.0.5", "@reflect-ui/core@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@reflect-ui/core/-/core-0.0.5.tgz#f50ae00e64300c4b698ab5c5374c6ac3bb5de873" - integrity sha512-lA6AYHCF8aSyOvGXbJZcmlB5ccxCaznhxvD8Hg1UjVdhcbLhMWDbzoYqbrkqh+R4im3KnYw5n6pWSSdoWioYhA== - dependencies: - "@reflect-ui/uiutils" "^0.1.2-1" - -"@reflect-ui/core@^0.0.9": +"@reflect-ui/core@0.0.2-rc.7", "@reflect-ui/core@0.0.5", "@reflect-ui/core@0.0.9", "@reflect-ui/core@^0.0.5", "@reflect-ui/core@^0.0.9": version "0.0.9" resolved "https://registry.yarnpkg.com/@reflect-ui/core/-/core-0.0.9.tgz#7283a2a3a1edde16282559d11f02e23d3bceda36" integrity sha512-MNJq+Pc45qZ0IvTYuvzCW2nxupVRfMtmin9vepABo2h1sTKdAmCK2kPfVLea6TNiF1baJDeQg7IyAN45JMuFdA== @@ -9204,7 +9214,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.0.24": +"@types/react@*", "@types/react@18.0.24", "@types/react@^17", "@types/react@^18.0.24", "@types/react@^18.0.25": version "18.0.24" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.24.tgz#2f79ed5b27f08d05107aab45c17919754cc44c20" integrity sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q== @@ -9213,24 +9223,6 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@^17": - version "17.0.62" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.62.tgz#2efe8ddf8533500ec44b1334dd1a97caa2f860e3" - integrity sha512-eANCyz9DG8p/Vdhr0ZKST8JV12PhH2ACCDYlFw6DIO+D+ca+uP4jtEDEpVqXZrh/uZdXQGwk7whJa3ah5DtyLw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@^18.0.25": - version "18.2.12" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.12.tgz#95d584338610b78bb9ba0415e3180fb03debdf97" - integrity sha512-ndmBMLCgn38v3SntMeoJaIrO6tGHYKMEBohCUmw8HoLLQdRMOIGXfeYaBTLe2lsFaSB3MOK1VXscYFnmLtTSmw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - "@types/resemblejs@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@types/resemblejs/-/resemblejs-4.1.0.tgz#1c150e0de4117b29f9d5d5231489edc7cef8263e" @@ -9991,6 +9983,11 @@ ansi-regex@^5.0.0, ansi-regex@^5.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" @@ -10015,6 +10012,11 @@ ansi-styles@^5.0.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + ansi-to-html@^0.6.11: version "0.6.15" resolved "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.15.tgz" @@ -12457,16 +12459,11 @@ cssesc@^3.0.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@^3.0.10, csstype@^3.0.2, csstype@^3.0.4, csstype@^3.0.8: +csstype@3.1.0, csstype@^3.0.10, csstype@^3.0.2, csstype@^3.0.4, csstype@^3.0.8, csstype@^3.1.1: version "3.1.0" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== -csstype@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - cuid@^2.1.8: version "2.1.8" resolved "https://registry.npmjs.org/cuid/-/cuid-2.1.8.tgz" @@ -13156,6 +13153,11 @@ dynamic-dedupe@^0.3.0: dependencies: xtend "^4.0.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" @@ -13212,6 +13214,11 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" @@ -14265,6 +14272,14 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" @@ -14817,6 +14832,17 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.2.7: + version "10.2.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" + integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.7.0" + glob@^5.0.15: version "5.0.15" resolved "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz" @@ -16498,6 +16524,15 @@ iterate-value@^1.0.2: es-get-iterator "^1.0.2" iterate-iterator "^1.0.1" +jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: version "10.8.5" resolved "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz" @@ -18027,6 +18062,11 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.14.1.tgz#8da8d2f5f59827edb388e63e459ac23d6d408fea" integrity sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA== +lru-cache@^9.1.1: + version "9.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.2.tgz#255fdbc14b75589d6d0e73644ca167a8db506835" + integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== + lz-string@^1.4.4: version "1.4.4" resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz" @@ -18711,6 +18751,13 @@ minimatch@^5.0.1, minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz" @@ -18803,6 +18850,11 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3. dependencies: yallist "^4.0.0" +"minipass@^5.0.0 || ^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" + integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== + minizlib@^1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz" @@ -20426,6 +20478,14 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.7.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.9.2.tgz#90f9d296ac5e37e608028e28a447b11d385b3f63" + integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== + dependencies: + lru-cache "^9.1.1" + minipass "^5.0.0 || ^6.0.2" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" @@ -22928,6 +22988,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -23386,6 +23451,15 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" @@ -23412,6 +23486,15 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + "string.prototype.matchall@^4.0.0 || ^3.0.1", string.prototype.matchall@^4.0.6: version "4.0.8" resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz" @@ -23490,6 +23573,13 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" @@ -23518,6 +23608,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" @@ -25552,6 +25649,15 @@ worker-rpc@^0.1.0: dependencies: microevent.ts "~0.1.1" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -25561,6 +25667,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" From eb25709a6dc64be5ba8c155287ca195b5a754946 Mon Sep 17 00:00:00 2001 From: Universe Date: Sat, 17 Jun 2023 18:06:30 +0900 Subject: [PATCH 06/16] styles --- editor/pages/qa/files/[key]/index.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/editor/pages/qa/files/[key]/index.tsx b/editor/pages/qa/files/[key]/index.tsx index d006b524..e6cf0110 100644 --- a/editor/pages/qa/files/[key]/index.tsx +++ b/editor/pages/qa/files/[key]/index.tsx @@ -23,9 +23,11 @@ export default function QAEditor({ key, data }: P) { return (

{k}

- A - B - B +
+ B + C + A +
); })} @@ -56,6 +58,11 @@ const Main = styled.main` width: 100%; height: auto; } + + .images { + display: flex; + flex-direction: row; + } } `; From 47f1e237eefab3859733cb01ecf9ce448b984725 Mon Sep 17 00:00:00 2001 From: Universe Date: Sat, 17 Jun 2023 18:06:42 +0900 Subject: [PATCH 07/16] fix symlink handling --- testing/report/src/index.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/testing/report/src/index.ts b/testing/report/src/index.ts index 0a27e522..121a3f0c 100644 --- a/testing/report/src/index.ts +++ b/testing/report/src/index.ts @@ -85,9 +85,6 @@ async function report() { let i = 0; for (const c of samples) { i++; - // create .coverage/:id folder - const coverage_set_path = path.join(coverage_path, c.id); - await mkdir(coverage_set_path); const { id: filekey } = c; let file; @@ -103,6 +100,10 @@ async function report() { continue; } + // create .coverage/:id folder + const coverage_set_path = path.join(coverage_path, c.id); + await mkdir(coverage_set_path); + const frames: ReadonlyArray = file.document.children .filter((c) => c.type === "CANVAS") .map((c) => c["children"]) @@ -170,11 +171,17 @@ async function report() { // if the exported is local fs path, then use copy instead if (await exists(exported)) { try { - // copy file with symlink - // rempve if already exists before linking new one - if (await exists(image_a)) { + // Check if image_a exists and remove + try { + await fs.lstat(image_a); // use stat to check if file exists (even broken one) await fs.unlink(image_a); + } catch (e) { + // Handle file not found error + if (e.code !== "ENOENT") { + throw e; + } } + await fs.symlink(exported, image_a); } catch (e) { // TODO: symlink still fails with "EEXIST: file already exists, symlink" @@ -189,7 +196,7 @@ async function report() { } if (!(await exists(image_a))) { - spinner.fail(`Image A not found - ${image_a}`); + spinner.fail(`Image A not found - ${image_a} from (${exported})`); continue; } From 565389d8b6f10dd5487e1364dd692f8af004e645 Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 18:52:10 +0900 Subject: [PATCH 08/16] mv --- editor/pages/{qa => tests}/index.tsx | 0 editor/pages/{qa/files => tests/reports}/[key]/index.tsx | 0 editor/pages/{qa/files => tests/reports}/index.tsx | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename editor/pages/{qa => tests}/index.tsx (100%) rename editor/pages/{qa/files => tests/reports}/[key]/index.tsx (100%) rename editor/pages/{qa/files => tests/reports}/index.tsx (100%) diff --git a/editor/pages/qa/index.tsx b/editor/pages/tests/index.tsx similarity index 100% rename from editor/pages/qa/index.tsx rename to editor/pages/tests/index.tsx diff --git a/editor/pages/qa/files/[key]/index.tsx b/editor/pages/tests/reports/[key]/index.tsx similarity index 100% rename from editor/pages/qa/files/[key]/index.tsx rename to editor/pages/tests/reports/[key]/index.tsx diff --git a/editor/pages/qa/files/index.tsx b/editor/pages/tests/reports/index.tsx similarity index 100% rename from editor/pages/qa/files/index.tsx rename to editor/pages/tests/reports/index.tsx From dafa88459af25ec42072898f194234b5559a7e9f Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 18:52:20 +0900 Subject: [PATCH 09/16] ch --- editor/pages/tests/reports/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/pages/tests/reports/index.tsx b/editor/pages/tests/reports/index.tsx index 852247cd..84cb93e9 100644 --- a/editor/pages/tests/reports/index.tsx +++ b/editor/pages/tests/reports/index.tsx @@ -20,7 +20,7 @@ export default function QAFilesPage({ files }) { {files.map((file) => ( Date: Sat, 17 Jun 2023 19:17:53 +0900 Subject: [PATCH 10/16] update global style --- editor/styles/global.css | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/editor/styles/global.css b/editor/styles/global.css index 47866019..caaaeaa0 100644 --- a/editor/styles/global.css +++ b/editor/styles/global.css @@ -9,6 +9,7 @@ html { overflow: hidden; height: 100%; overscroll-behavior-x: none; + background-color: rgb(20, 20, 20); } body { overscroll-behavior-x: none; @@ -29,15 +30,15 @@ h4, h5, h6, p { - color: rgba(0, 0, 0, 0.9); + color: white; } a { - color: rgba(0, 0, 0, 0.7); + color: rgba(255, 255, 255, 0.7); } a:hover { - color: rgba(0, 0, 0, 0.9); + color: rgba(255, 255, 255, 0.9); } .white { From eb4f1a269cc946b319b4f3ee5b53befba0158600 Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 19:18:07 +0900 Subject: [PATCH 11/16] add default option --- testing/server/bin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/server/bin.ts b/testing/server/bin.ts index ec0d171a..173800c8 100644 --- a/testing/server/bin.ts +++ b/testing/server/bin.ts @@ -14,7 +14,7 @@ const argv = yargs(hideBin(process.argv)) .option("reports", { description: "The path to the folder with the files", type: "string", - demandOption: true, + default: defaultOptions.reports, }) .help() .alias("help", "h").argv as ServerOptions; From 4eb8e11098e6e6e01c22b19cbdabb1c09b8be356 Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 19:18:23 +0900 Subject: [PATCH 12/16] add how to setup page --- editor/pages/tests/reports/how-to-setup.tsx | 66 +++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 editor/pages/tests/reports/how-to-setup.tsx diff --git a/editor/pages/tests/reports/how-to-setup.tsx b/editor/pages/tests/reports/how-to-setup.tsx new file mode 100644 index 00000000..ba3a283b --- /dev/null +++ b/editor/pages/tests/reports/how-to-setup.tsx @@ -0,0 +1,66 @@ +import Head from "next/head"; +import { useRouter } from "next/router"; +import React from "react"; + +export default function HowToSetupReports() { + const router = useRouter(); + + return ( + <> + + How to setup local server for @codetest/reports + + +
+

+ How to setup local server for @codetest/reports +

+

+ @codetest/reports is a package that allows you to run + engine tests locally, due to its high maintainance cost, we don't + provide official reports server yet. +
+
+ To generate reports, run the following command: +
+
+ + cd testing/reports +
+ yarn build +
+ yarn start +
+
+
+ To run local reports server, run the following command: +
+
+ + cd testing/server +
+ yarn dev +
+
+
+ Go back to the page after server has started +
+
+ +

+
+ + ); +} From 1e192b088acd9744f3d340bab903e35b4a549ac1 Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 19:18:34 +0900 Subject: [PATCH 13/16] update tests/reports page with rd and styles --- editor/pages/_app.tsx | 1 - editor/pages/tests/reports/index.tsx | 54 ++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/editor/pages/_app.tsx b/editor/pages/_app.tsx index 57b4f433..5601a28d 100644 --- a/editor/pages/_app.tsx +++ b/editor/pages/_app.tsx @@ -13,7 +13,6 @@ function GlobalCss() { - QA - Files + @codetest/reports -
-

QA - Files

+
+

+ @codetest/reports +

+

+ reports coverage generated by @codetest/reports (locally) + will be listed here +

{files.map((file) => ( - {file} + + + + @@ -35,6 +57,23 @@ export default function QAFilesPage({ files }) { ); } +const Row = styled.div` + cursor: pointer; + padding: 16px; + background: rgba(0, 0, 0, 0.1); + border-radius: 4; + border: 1px solid rgba(255, 255, 255, 0.1); + + a { + display: flex; + align-items: center; + } + + &:hover { + background: rgba(0, 0, 0, 0.2); + } +`; + export async function getServerSideProps(context: any) { const client = Client({ baseURL: "http://localhost:6627", @@ -50,7 +89,10 @@ export async function getServerSideProps(context: any) { }; } catch (e) { return { - notFound: true, + redirect: { + destination: "/tests/reports/how-to-setup", + permanent: false, + }, }; } } From 161ff7f6961e4496fc02a7510bec620fc2b80f4f Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 20:27:36 +0900 Subject: [PATCH 14/16] add diff view --- editor/pages/tests/reports/[key]/index.tsx | 148 +++++++++++++++++---- 1 file changed, 121 insertions(+), 27 deletions(-) diff --git a/editor/pages/tests/reports/[key]/index.tsx b/editor/pages/tests/reports/[key]/index.tsx index e6cf0110..ee90a8be 100644 --- a/editor/pages/tests/reports/[key]/index.tsx +++ b/editor/pages/tests/reports/[key]/index.tsx @@ -3,65 +3,160 @@ import Head from "next/head"; import { InferGetServerSidePropsType } from "next"; import styled from "@emotion/styled"; import { Client, NodeReportCoverage } from "@codetest/editor-client"; +import { CircleIcon } from "@radix-ui/react-icons"; type P = InferGetServerSidePropsType; -export default function QAEditor({ key, data }: P) { +export default function ReportPage({ data }: P) { return ( <> - QA - {key} + Report Coverages - @codetest/reports {/* */}
+

+ @codetest/reports +

{/*
{JSON.stringify(data, null, 2)}
*/} -
+
{Object.keys(data).map((k) => { const record: NodeReportCoverage = data[k]; - return ( -
-

{k}

-
- B - C - A -
-
- ); + return ; })}
+
); } const Main = styled.main` + font-family: monospace; + width: 400px; + margin: auto; + /* */ - .frames { - width: 100%; + .nodes { display: flex; flex-direction: column; - align-items: center; - flex-wrap: wrap; + gap: 16px; } - .item { - display: flex; - flex-direction: column; + footer { + height: 200px; + } +`; + +function Item({ id, a, b, diff, report }: NodeReportCoverage & { id: string }) { + const [focus, setFocus] = React.useState<"a" | "b" | null>(null); + + return ( + +
+

+ + {id} {focus && ({focus})} +

+
+
+ A + B + C +
setFocus("a")} + onMouseLeave={() => setFocus(null)} + /> +
setFocus("b")} + onMouseLeave={() => setFocus(null)} + /> +
+ + ); +} + +const ItemContainer = styled.div` + display: flex; + flex-direction: column; + + border-radius: 2px; + border: 1px solid rgba(255, 255, 255, 0.1); + overflow: hidden; + + width: 400px; + height: 100%; + + header { + padding: 16px; + .title { + display: flex; + align-items: center; + gap: 8px; + } + } - width: 400px; - height: 400px; + .view { + position: relative; + display: flex; + flex-direction: row; + align-items: center; - img { + .a, + .b, + .c { + position: relative; + z-index: 1; + flex: 1 0 auto; width: 100%; height: auto; } - .images { - display: flex; - flex-direction: row; + .a, + .b { + pointer-events: none; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + opacity: 0.5; + transition: opacity 0.1s ease-in-out; + } + + &[data-focus="a"] .a { + z-index: 9; + opacity: 1; + } + + &[data-focus="b"] .b { + z-index: 9; + opacity: 1; + } + + .hover-area { + position: absolute; + top: 0; + bottom: 0; + width: 50%; + height: 100%; + z-index: 2; + } + + .hover-area-left { + cursor: w-resize; + left: 0; + } + + .hover-area-right { + cursor: e-resize; + right: 0; } } `; @@ -78,7 +173,6 @@ export async function getServerSideProps(context: any) { return { props: { - key, data, }, }; From b718fbe32d4322bcdf6370c995fdd62bb4a54fac Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 21:08:47 +0900 Subject: [PATCH 15/16] styles --- editor-packages/editor-ui/icon-button.tsx | 3 + editor/pages/tests/reports/[key]/index.tsx | 70 ++++++++++++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/editor-packages/editor-ui/icon-button.tsx b/editor-packages/editor-ui/icon-button.tsx index 9feb70cb..8cbe47fb 100644 --- a/editor-packages/editor-ui/icon-button.tsx +++ b/editor-packages/editor-ui/icon-button.tsx @@ -4,11 +4,13 @@ import styled from "@emotion/styled"; export const IconButton = React.forwardRef(function ( { children, + title, outline, onClick, disabled, ...props }: React.PropsWithChildren<{ + title?: string; outline?: React.CSSProperties["outline"]; onClick?: React.MouseEventHandler; disabled?: boolean; @@ -20,6 +22,7 @@ export const IconButton = React.forwardRef(function ( ref={ref} onClick={onClick} disabled={disabled} + title={title} {...props} style={{ outline, diff --git a/editor/pages/tests/reports/[key]/index.tsx b/editor/pages/tests/reports/[key]/index.tsx index ee90a8be..848b2f06 100644 --- a/editor/pages/tests/reports/[key]/index.tsx +++ b/editor/pages/tests/reports/[key]/index.tsx @@ -3,11 +3,15 @@ import Head from "next/head"; import { InferGetServerSidePropsType } from "next"; import styled from "@emotion/styled"; import { Client, NodeReportCoverage } from "@codetest/editor-client"; -import { CircleIcon } from "@radix-ui/react-icons"; - +import { CircleIcon, LightningBoltIcon, CodeIcon } from "@radix-ui/react-icons"; +import { IconButton } from "@code-editor/ui"; type P = InferGetServerSidePropsType; -export default function ReportPage({ data }: P) { +export default function ReportPage({ _key, data }: P) { + const onRegenerate = () => { + alert("regenerate (not implemented)"); + }; + return ( <> @@ -15,9 +19,17 @@ export default function ReportPage({ data }: P) { {/* */}
-

- @codetest/reports -

+
+ + @codetest/reports +

{_key}

+
+
+ + + +
+
{/*
{JSON.stringify(data, null, 2)}
*/} @@ -34,6 +46,7 @@ export default function ReportPage({ data }: P) { } const Main = styled.main` + color: white; font-family: monospace; width: 400px; margin: auto; @@ -45,6 +58,23 @@ const Main = styled.main` gap: 16px; } + header.header { + margin: 120px 0 40px 0; + display: flex; + align-items: center; + justify-content: space-between; + + h1 { + margin: 0; + } + + .actions { + display: flex; + align-items: center; + gap: 4px; + } + } + footer { height: 200px; } @@ -53,6 +83,14 @@ const Main = styled.main` function Item({ id, a, b, diff, report }: NodeReportCoverage & { id: string }) { const [focus, setFocus] = React.useState<"a" | "b" | null>(null); + const onInspect = () => { + alert("inspect (not implemented)"); + }; + + const onRegenerate = () => { + alert("regenerate (not implemented)"); + }; + return (
@@ -60,6 +98,14 @@ function Item({ id, a, b, diff, report }: NodeReportCoverage & { id: string }) { {id} {focus && ({focus})}

+
+ + + + + + +
A @@ -92,12 +138,23 @@ const ItemContainer = styled.div` height: 100%; header { + color: white; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; padding: 16px; .title { display: flex; align-items: center; gap: 8px; } + + .actions { + display: flex; + align-items: center; + gap: 4px; + } } .view { @@ -173,6 +230,7 @@ export async function getServerSideProps(context: any) { return { props: { + _key: key, data, }, }; From 43bb62d12399996f9eade05a18ff191a18a65af6 Mon Sep 17 00:00:00 2001 From: softmarshmallow Date: Sat, 17 Jun 2023 21:27:10 +0900 Subject: [PATCH 16/16] fix styles --- editor/components/community-files/readme.tsx | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/editor/components/community-files/readme.tsx b/editor/components/community-files/readme.tsx index b3058376..f2991acc 100644 --- a/editor/components/community-files/readme.tsx +++ b/editor/components/community-files/readme.tsx @@ -176,6 +176,7 @@ export function Readme({ } const ReadmeWrapper = styled.main` + color: black; margin: auto; width: 100%; @@ -183,6 +184,28 @@ const ReadmeWrapper = styled.main` overflow: hidden; overflow-y: scroll; + h1, + h2, + h3, + h4, + h5, + h6 { + color: black; + } + + p { + color: black; + } + + a { + color: black; + opacity: 0.8; + + &:hover { + opacity: 1; + } + } + .cta { display: flex; flex-direction: column;