@explorable-viz/fluid 0.12.4 → 0.12.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorable-viz/fluid",
3
- "version": "0.12.4",
3
+ "version": "0.12.5",
4
4
  "description": "A functional programming language which integrates a bidirectional dynamic analysis, connecting outputs to data sources in a fine-grained way. Fluid is implemented in PureScript and runs in the browser.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,8 @@
21
21
  "dist/fluid/fluid/lib",
22
22
  "output-es",
23
23
  "web/lib",
24
- "website/article"
24
+ "website/article",
25
+ "script/webtest-lib.mjs"
25
26
  ],
26
27
  "scripts": {
27
28
  "build": "./script/build.sh",
@@ -27,8 +27,14 @@ cp -r "$SRC" "$DEST"
27
27
 
28
28
  # Rewrite workspace:* dependency to the actual installed version
29
29
  sed -i.bak "s/\"workspace:\*\"/\"$VERSION\"/" "$DEST/package.json"
30
+ # Remove monorepo-relative test script
31
+ sed -i.bak "s|\"test\":.*test-website.sh\"|\"test\": \"echo 'No standalone test — run from project root'\"|" "$DEST/package.json"
30
32
  rm -f "$DEST/package.json.bak"
31
33
 
34
+ # Rewrite webtest-lib import path for installed context
35
+ sed -i.bak "s|../../script/webtest-lib.mjs|../../$NPM_ROOT/script/webtest-lib.mjs|" "$DEST/test.mjs"
36
+ rm -f "$DEST/test.mjs.bak"
37
+
32
38
  # Recreate symlinks pointing into node_modules
33
39
  rm -rf "$DEST/static/fluid/lib"
34
40
  ln -s "../../../../$NPM_ROOT/dist/fluid/fluid/lib" "$DEST/static/fluid/lib"
@@ -0,0 +1,101 @@
1
+ import puppeteer from "puppeteer"
2
+
3
+ const TIMEOUT = 60000
4
+ const LOGGING = true
5
+ const HEADLESS = true
6
+ const VIEWPORT = { width: 1200, height: 800, deviceScaleFactor: 1.0 }
7
+
8
+ function log(msg) {
9
+ if (LOGGING) console.log(msg)
10
+ }
11
+
12
+ function testOutcome(pass, msg) {
13
+ const sym = pass ? "\x1b[32m ✔\x1b[0m" : "\x1b[31m ✖\x1b[0m"
14
+ console.log(`${sym} ${msg}`)
15
+ if (!pass) throw new Error("Test failed")
16
+ }
17
+
18
+ async function launchBrowser(browserName) {
19
+ return puppeteer.launch({
20
+ browser: browserName,
21
+ headless: HEADLESS,
22
+ defaultViewport: VIEWPORT,
23
+ })
24
+ }
25
+
26
+ export async function waitFor(page, selector) {
27
+ log(`Waiting for ${selector}`)
28
+ try {
29
+ await page.waitForSelector(selector, { timeout: TIMEOUT, visible: true })
30
+ log("-> found")
31
+ testOutcome(true, `${selector}: exists`)
32
+ } catch (e) {
33
+ testOutcome(false, `${selector}: ${e.message}`)
34
+ }
35
+ }
36
+
37
+ export async function waitForHidden(page, selector) {
38
+ log(`Waiting for ${selector} (hidden)`)
39
+ await page.waitForSelector(selector, { timeout: TIMEOUT, visible: false })
40
+ log("-> found")
41
+ }
42
+
43
+ export async function click(page, selector) {
44
+ await page.click(selector)
45
+ testOutcome(true, `${selector}: click`)
46
+ }
47
+
48
+ export async function checkAttribute(page, selector, attr, expected) {
49
+ const found = await page.$eval(selector, (el, a) => el.getAttribute(a), attr)
50
+ const pass = found === expected
51
+ const errorMsg = pass ? "" : ` (got "${found}")`
52
+ testOutcome(pass, `${selector}: ${attr} == "${expected}"${errorMsg}`)
53
+ }
54
+
55
+ export async function checkAttributeContains(page, selector, attr, expected) {
56
+ const found = await page.$eval(selector, (el, a) => el.getAttribute(a), attr)
57
+ const pass = found.includes(expected)
58
+ const errorMsg = pass ? "" : ` (got "${found}")`
59
+ testOutcome(pass, `${selector}: ${attr} contains "${expected}"${errorMsg}`)
60
+ }
61
+
62
+ export async function checkTextContent(page, selector, expected) {
63
+ await waitFor(page, selector)
64
+ const text = await page.$eval(selector, el => el.textContent)
65
+ const pass = text === expected
66
+ testOutcome(pass, `${selector}: text == "${expected}"${pass ? "" : ` (got "${text}")`}`)
67
+ }
68
+
69
+ export async function checkComputedStyle(page, selector, property, expected) {
70
+ await waitFor(page, selector)
71
+ const value = await page.$eval(selector, (el, prop) => getComputedStyle(el)[prop], property)
72
+ const pass = value === expected
73
+ testOutcome(pass, `${selector}: ${property} == "${expected}"${pass ? "" : ` (got "${value}")`}`)
74
+ }
75
+
76
+ export async function clickToggle(page) {
77
+ await waitFor(page, "#grid.data-pane-hidden")
78
+ const toggle = "button[title='Show data pane']"
79
+ await waitFor(page, toggle)
80
+ await click(page, toggle)
81
+ await waitFor(page, "#grid:not(.data-pane-hidden)")
82
+ }
83
+
84
+ async function browserTests(url, browserName, tests) {
85
+ log(`browserTests: ${browserName}`)
86
+ const browser = await launchBrowser(browserName)
87
+ const page = await browser.newPage()
88
+ for (const test of tests) {
89
+ await page.goto(url)
90
+ await test(page)
91
+ }
92
+ await browser.close()
93
+ }
94
+
95
+ const BASE_URL = process.env.BASE_URL || "http://127.0.0.1:8080"
96
+
97
+ export async function testURL(suffix, tests) {
98
+ const url = `${BASE_URL}/${suffix}`
99
+ await browserTests(url, "chrome", tests)
100
+ await browserTests(url, "firefox", tests)
101
+ }