Skip to content

Commit

Permalink
MP query freshness checker prototype (#4462)
Browse files Browse the repository at this point in the history
* first try

* more work

* more

* boom, queries without vars work

* wow, pretty sweet!

* get token and id after logging in

* try some automation

* maybe not this

* hm maybe thats the right place

* add puppeteer orb

* maybe now

* maybe now

* read from env

* move things to a func

* extract login

* maximum 🤦‍♂️

* works with more errors

* typescript

* comments

* try

* hm

* lets go

* boom

* always run

* again

* again

* ok?

* use new node from orb
  • Loading branch information
pvinis committed Feb 27, 2021
1 parent 95bfdfe commit d95bc8f
Show file tree
Hide file tree
Showing 4 changed files with 371 additions and 10 deletions.
31 changes: 29 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# .circleci/config.yml

version: 2.1

orbs:
Expand Down Expand Up @@ -226,6 +224,34 @@ jobs:
name: Prevent Strictness Regressions
command: node scripts/strictness-migration.js check-pr

check-metaphysics-freshness:
executor:
name: node/default
tag: "14.13.1"
steps:
- checkout
- run:
name: apt-get update
command: sudo apt-get update --fix-missing
- run:
name: Install Headless Chrome dependencies for puppeteer
# from https://github.com/threetreeslight/puppeteer-orb/blob/master/orb.yml
command: |
sudo apt-get install --fix-missing -yq \
gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates \
fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
- generate-checksums
- install-node-modules
- run:
name: Generate queries json
command: yarn relay
- run:
name: Check Metaphysics freshness
command: yarn ts-node ./metaphysics-queries-freshness-tests/test-freshness.ts

build-test-js:
executor:
name: node/default
Expand Down Expand Up @@ -412,6 +438,7 @@ workflows:

test-build-deploy:
jobs:
- check-metaphysics-freshness
- check-pr:
filters:
branches:
Expand Down
153 changes: 153 additions & 0 deletions metaphysics-queries-freshness-tests/test-freshness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!/usr/bin/env yarn ts-node

require("dotenv").config()

import { GraphQLClient } from "graphql-request"
import { values } from "lodash"
import { exit, stdout } from "process"
import puppeteer from "puppeteer"

const login = async (): Promise<{ userId: string; accessToken: string }> => {
console.log("Logging in..")
const browser = await puppeteer.launch({ headless: true })
const page = await browser.newPage()
await page.goto("https://staging.artsy.net")
await page.click('aria/button[name="Log in"]')
await page.click('aria/textbox[name="Enter your email address"]')
await page.type('aria/textbox[name="Enter your email address"]', process.env.FRESHNESS_TEST_EMAIL ?? "missing email")
await page.click('aria/textbox[name="Enter your password"]')
await page.type('aria/textbox[name="Enter your password"]', process.env.FRESHNESS_TEST_PASSWORD ?? "missing password")
await page.click('aria/pushbutton[name="Log in"]')
await page.waitForNavigation()
const { id: userId, accessToken } = await page.evaluate("sd.CURRENT_USER")
console.log("Logged in.")
return { userId, accessToken }
}

const doIt = async (): Promise<never> => {
const { userId, accessToken } = await login()
const metaphysics = new GraphQLClient("https://metaphysics-staging.artsy.net/v2", {
headers: {
"X-Access-Token": accessToken,
"X-User-Id": userId,
},
})

const allQueries = values(require("../data/complete.queryMap.json")) as string[]
const problemQueries = allQueries.filter(
(q) =>
q.includes("$conversationID") ||
q.includes("ArtistRailNewSuggestionQuery") ||
q.includes("ArtistSeriesQuery") ||
q.includes("ArtworkMediumQuery") ||
q.includes("AuctionResultQuery") ||
q.includes("AutosuggestResultsQuery") ||
q.includes("BidFlowQuery") ||
q.includes("BidderPositionQuery") ||
q.includes("BottomTabsModelFetchCurrentUnreadConversationCountQuery") ||
q.includes("ConfirmBidRefetchQuery") ||
q.includes("ConsignmentsArtistQuery") ||
q.includes("ConversationQuery") ||
q.includes("FairArticlesQuery") ||
q.includes("FairExhibitorsQuery") ||
q.includes("FeatureQuery") ||
q.includes("GeneQuery") ||
q.includes("InboxOldQuery") ||
q.includes("MapRendererQuery") ||
q.includes("PartnerLocationsQuery") ||
q.includes("PartnerQuery") ||
q.includes("PartnerRefetchQuery") ||
q.includes("PriceSummaryQuery") ||
q.includes("RegistrationFlowQuery") ||
q.includes("SaleAboveTheFoldQuery") ||
q.includes("SaleActiveBidsRefetchQuery") ||
q.includes("SaleBelowTheFoldQuery") ||
q.includes("SaleInfoQueryRendererQuery") ||
q.includes("SaleRefetchQuery") ||
q.includes("SelectMaxBidRefetchQuery") ||
q.includes("ShowMoreInfoQuery") ||
q.includes("ShowQuery") ||
q.includes("VanityURLEntityQuery")
)
const allQueriesToCheck = allQueries.filter((q) => !problemQueries.includes(q))
const allNonTestQueries = allQueriesToCheck.filter(
(q) => !q.includes("Test") && !q.includes("Mock") && !q.includes("Fixtures")
)
const queries = allNonTestQueries.filter((q) => q.startsWith("query"))
const queriesWithoutVars = queries.filter((q) => !q.includes("$"))
const queriesWithCursor = queries.filter((q) => q.includes("$cursor"))
const queriesWithVars = queries.filter((q) => !queriesWithoutVars.includes(q) && !queriesWithCursor.includes(q))
const mutations = allNonTestQueries.filter((q) => q.startsWith("mutation"))

console.warn(`Skipping ${mutations.length} mutations`)
console.log(`Skipping ${allQueries.length - allNonTestQueries.length} test queries`)
console.warn(`Skipping ${queriesWithCursor.length} queries with cursors`)

type Error = { request: string; error: string }
const errors: Error[] = [] as Error[]
const executeRequests = async (
requests: string[],
description: string,
options: { verbose?: boolean; vars?: { [Var: string]: any } } = { verbose: false }
) => {
const log = (...args: Parameters<typeof console.log>) => {
if (options.verbose) {
console.log(...args)
}
}

console.log(`Running ${requests.length} ${description}`)
await Promise.all(
requests.map(async (req) => {
try {
log(req)
const response = await metaphysics.request(req, options.vars)
stdout.write(".")
log(JSON.stringify(response))
} catch (e) {
stdout.write("x")
errors.push({ request: req, error: e })
}
})
)
console.log("")
}

await executeRequests(queriesWithoutVars, "no-var queries")

await executeRequests(queriesWithVars, "var queries", {
vars: {
artworkID: "felipe-pantone-subtractive-variability-silk-robe-w-slash-j-balvin",
artworkSlug: "felipe-pantone-subtractive-variability-silk-robe-w-slash-j-balvin",
fairID: "london-art-fair-edit",
citySlug: "athens-greece",
artistInternalID: "4dd1584de0091e000100207c", // banksy
artistSlug: "banksy",
artistID: "banksy",
medium: "prints",
collectionID: "agnes-martin-lithographs",
viewingRoomID: "movart-mario-macilau-circle-of-memories",
isPad: false,
heroImageVersion: "NARROW",
count: 4,
},
})

// end game
if (errors.length !== 0) {
console.error(`Oh noes! ${errors.length} queries failed!`)
errors.map(({ request, error }) => {
console.warn("- The following query:")
console.log(request)
console.warn("failed with error:")
console.log(error)
})
console.error(`Again, ${errors.length} queries failed. Look above for more details.`)
exit(-1)
}
console.log("Success! Our queries are so so fresh.")
exit(0)
}

doIt()

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,12 @@
"danger": "6.1.1",
"danger-plugin-jest": "1.1.0",
"dedent": "0.7.0",
"dotenv": "8.2.0",
"enzyme": "3.9.0",
"enzyme-adapter-react-16": "1.13.0",
"glob": "7.1.6",
"graphql": "14.5.6",
"graphql-request": "3.4.0",
"husky": "4.2.5",
"jest": "25.2.7",
"jest-fetch-mock": "^3.0.3",
Expand All @@ -203,6 +205,7 @@
"postinstall-prepare": "1.0.1",
"prettier": "^2.2.0",
"pull-lock": "1.0.0",
"puppeteer": "^7.1.0",
"react-dom": "16.8.3",
"react-relay-network-modern": "4.7.1",
"react-test-renderer": "16.13.1",
Expand Down
Loading

0 comments on commit d95bc8f

Please sign in to comment.