diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 9c373616b26..00000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,606 +0,0 @@
-version: 2.1
-orbs:
- browser-tools: circleci/browser-tools@2.4.0
-
-# Inspired by:
-# https://github.com/CircleCI-Public/circleci-demo-workflows/blob/workspace-forwarding/.circleci/config.yml
-# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
-#
-# For list of official CircleCI node.js images, go to:
-# https://hub.docker.com/r/cimg/node/tags/
-
-jobs:
- install-and-cibuild:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - checkout
- - run:
- name: Set up build environment
- command: .circleci/env_build.sh
- - run:
- name: Pretest
- command: npm run pretest
- - run:
- name: CI-Build
- command: npm run cibuild
- - run:
- name: Delete git
- command: rm -rf .git
- - persist_to_workspace:
- root: /home/circleci
- paths:
- - plotly.js
-
- timezone-jasmine:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- working_directory: ~/plotly.js
- steps:
- - run: sudo apt-get update
- - browser-tools/install_browser_tools:
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "136.0.7103.113"
- - attach_workspace:
- at: ~/
- - run:
- name: Run hover_label test in UTC timezone
- environment:
- TZ: "UTC"
- command: date && npm run test-jasmine hover_label
- - run:
- name: Run hover_label test in Europe/Berlin timezone
- environment:
- TZ: "Europe/Berlin"
- command: date && npm run test-jasmine hover_label
- - run:
- name: Run hover_label test in Asia/Tokyo timezone
- environment:
- TZ: "Asia/Tokyo"
- command: date && npm run test-jasmine hover_label
- - run:
- name: Run hover_label test in America/Toronto timezone
- environment:
- TZ: "America/Toronto"
- command: date && npm run test-jasmine hover_label
-
- no-gl-jasmine:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- parallelism: 4
- working_directory: ~/plotly.js
- steps:
- - run: sudo apt-get update
- - browser-tools/install_browser_tools:
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "136.0.7103.113"
- - attach_workspace:
- at: ~/
- - run:
- name: Run jasmine tests (part A)
- command: .circleci/test.sh no-gl-jasmine
-
- webgl-jasmine:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- parallelism: 8
- working_directory: ~/plotly.js
- steps:
- - run: sudo apt-get update
- - browser-tools/install_browser_tools:
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "136.0.7103.113"
- - attach_workspace:
- at: ~/
- - run:
- name: Run jasmine tests (part B)
- command: .circleci/test.sh webgl-jasmine
-
- virtual-webgl-jasmine:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- parallelism: 8
- working_directory: ~/plotly.js
- steps:
- - run: sudo apt-get update
- - browser-tools/install_browser_tools:
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "136.0.7103.113"
- - attach_workspace:
- at: ~/
- - run:
- name: Run jasmine tests (part B)
- command: .circleci/test.sh virtual-webgl-jasmine
-
- webgl-jasmine-chromeLatest:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- parallelism: 8
- working_directory: ~/plotly.js
- steps:
- - browser-tools/install_browser_tools: &browser-versions
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "143.0.7499.192" # TEMPORARY pin until WebGL issues with 144 are resolved
- - attach_workspace:
- at: ~/
- - run:
- name: Run jasmine tests (part B)
- command: .circleci/test.sh webgl-jasmine
-
- flaky-no-gl-jasmine:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- working_directory: ~/plotly.js
- steps:
- - run: sudo apt-get update
- - browser-tools/install_browser_tools:
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "136.0.7103.113"
- - attach_workspace:
- at: ~/
- - run:
- name: Run jasmine tests (part C)
- command: .circleci/test.sh flaky-no-gl-jasmine
-
- bundle-jasmine:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- working_directory: ~/plotly.js
- steps:
- - run: sudo apt-get update
- - browser-tools/install_browser_tools:
- install_firefox: false
- install_geckodriver: false
- install_chrome: true
- chrome_version: "136.0.7103.113"
- - attach_workspace:
- at: ~/
- - run:
- name: Run jasmine tests (part D)
- command: .circleci/test.sh bundle-jasmine
-
- mathjax-firefoxLatest:
- docker:
- # need '-browsers' version to test in real (xvfb-wrapped) browsers
- - image: cimg/node:18.20.4-browsers
- environment:
- # Alaska time (arbitrary timezone to test date logic)
- TZ: "America/Anchorage"
- working_directory: ~/plotly.js
- steps:
- - browser-tools/install_browser_tools:
- install_chrome: false
- install_chromedriver: false
- - attach_workspace:
- at: ~/
- - run:
- name: Test MathJax on firefox-latest
- command: .circleci/test.sh mathjax-firefox
-
- make-baselines-virtual-webgl:
- parallelism: 8
- docker:
- - image: cimg/python:3.12.11
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run: sudo apt-get update
- - run:
- name: Install kaleido, plotly.io and required fonts
- command: .circleci/env_image.sh
- - run:
- name: Create png files using virtual-webgl & WebGL v1
- command: .circleci/test.sh make-baselines-virtual-webgl
- - persist_to_workspace:
- root: ~/
- paths:
- - plotly.js
-
- make-baselines-mathjax3:
- docker:
- - image: cimg/python:3.12.11
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run: sudo apt-get update
- - run:
- name: Install kaleido, plotly.io and required fonts
- command: .circleci/env_image.sh
- - run:
- name: Create mathjax v3 png files
- command: .circleci/test.sh make-baselines-mathjax3
- - persist_to_workspace:
- root: ~/
- paths:
- - plotly.js
-
- make-baselines:
- parallelism: 12
- docker:
- - image: cimg/python:3.12.11
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run: sudo apt-get update
- - run:
- name: Install kaleido, plotly.io and required fonts
- command: .circleci/env_image.sh
- - run:
- name: Create all png files
- command: .circleci/test.sh make-baselines
- - persist_to_workspace:
- root: ~/
- paths:
- - plotly.js
-
- make-baselines-b64:
- parallelism: 12
- docker:
- - image: cimg/python:3.12.11
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run: sudo apt-get update
- - run:
- name: Install kaleido, plotly.io and required fonts
- command: .circleci/env_image.sh
- - run:
- name: Create all png files
- command: .circleci/test.sh make-baselines-b64
- - persist_to_workspace:
- root: ~/
- paths:
- - plotly.js
-
- test-baselines:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Compare pixels
- command: .circleci/test.sh test-image ; find build -maxdepth 1 -type f -delete
- - image-diff-message
- - store_artifacts:
- path: build
- destination: /
-
- test-baselines-virtual-webgl:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Compare pixels
- command: .circleci/test.sh test-image-virtual-webgl ; find build -maxdepth 1 -type f -delete
- - image-diff-message
- - store_artifacts:
- path: build
- destination: /
-
- test-baselines-b64:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Compare pixels
- command: .circleci/test.sh test-image ; find build -maxdepth 1 -type f -delete
- - image-diff-message
- - store_artifacts:
- path: build
- destination: /
-
- test-baselines-mathjax3:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Compare pixels of mathjax v3 baselines
- command: .circleci/test.sh test-image-mathjax3
- - image-diff-message
- - store_artifacts:
- path: build
- destination: /
-
- make-exports:
- docker:
- - image: cimg/python:3.12.11
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run: sudo apt-get update
- - run:
- name: Install kaleido, plotly.io and required fonts
- command: .circleci/env_image.sh
- - run:
- name: Install poppler-utils to have pdftops for exporting eps
- command: |
- sudo apt-get update --allow-releaseinfo-change
- sudo apt-get install poppler-utils
- - run:
- name: Create svg, jpg, jpeg, webp, pdf and eps files
- command: sudo python3 test/image/make_exports.py
- - persist_to_workspace:
- root: ~/
- paths:
- - plotly.js
-
- test-exports:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Test export sizes
- command: node test/image/export_test.js ; find build -maxdepth 1 -type f -delete
- - store_artifacts:
- path: build
- destination: /
-
- mock-validation:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Test validation using node.js and jsdom
- command: npm run test-plain-obj
- - run:
- name: Validate mocks
- command: npm run test-mock
-
- source-syntax:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - attach_workspace:
- at: ~/
- - run:
- name: Run syntax tests on source files
- command: .circleci/test.sh source-syntax
-
- publish-dist: &publish-dist
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - checkout
- - run:
- name: Set up build environment
- command: .circleci/env_build.sh
- - run:
- name: Preview CHANGELOG for next release (only on master)
- command: |
- if [ $CIRCLE_BRANCH == "master" ]
- then npm run use-draftlogs && git --no-pager diff --color-words CHANGELOG.md || true
- fi
- - run:
- name: Set draft version in package.json
- command: |
- node --eval "var fs = require('fs'); var inOut = './package.json'; var data = JSON.parse(fs.readFileSync(inOut)); var a = process.argv; data.version = a[a.length - 1].replace('v', ''); fs.writeFileSync(inOut, JSON.stringify(data, null, 2) + '\n');" `git describe`
- - run:
- name: View package.json diff between previous and next releases (including above draft version change)
- command: git --no-pager diff --color-words tags/$(git describe --tags --abbrev=0) package.json || true
- - run:
- name: Build dist/
- command: npm run build
- - store_artifacts:
- path: dist
- destination: dist
- - run:
- name: View dist/README.md diff between previous and next releases (including new bundle sizes)
- command: git --no-pager diff --color-words tags/$(git describe --tags --abbrev=0) dist/README.md || true
- - run:
- name: Preview plot-schema diff between previous and next releases (only on master)
- command: |
- if [ $CIRCLE_BRANCH == "master" ]
- then git --no-pager diff tags/$(git describe --tags --abbrev=0) dist/plot-schema.json || true
- fi
- - run:
- name: Pack tarball
- command: |
- npm pack
- version=$(node --eval "console.log(require('./package.json').version)")
- mv plotly.js-$version.tgz plotly.js.tgz
- - store_artifacts:
- path: plotly.js.tgz
- destination: /plotly.js.tgz
- - run:
- name: Show URLs to build files
- command: |
- PROJECT_NUM=45646037
- echo https://$CIRCLE_BUILD_NUM-$PROJECT_NUM-gh.circle-artifacts.com/0/plotly.js.tgz
- echo https://$CIRCLE_BUILD_NUM-$PROJECT_NUM-gh.circle-artifacts.com/0/dist/plotly.js
- echo https://$CIRCLE_BUILD_NUM-$PROJECT_NUM-gh.circle-artifacts.com/0/dist/plotly.min.js
- echo https://$CIRCLE_BUILD_NUM-$PROJECT_NUM-gh.circle-artifacts.com/0/dist/plot-schema.json
- - run:
- name: Test plot-schema.json diff - If failed, after (npm start) you could run (npm run schema && git add test/plot-schema.json && git commit -m "update plot-schema diff")
- command: diff --unified --color dist/plot-schema.json test/plot-schema.json
-
- publish-dist-node-v22:
- <<: *publish-dist
- docker:
- - image: cimg/node:22.14.0
-
- test-stackgl-bundle:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - checkout
- - run:
- name: Set up build environment
- command: cd stackgl_modules && npm ci
- - run:
- name: Bundle bundle-stackgl/index.js
- command: cd stackgl_modules && cp index.js INDEX.js && npm run bundle-stackgl
- - run:
- name: Test stackgl_modules/index.js diff - If failed please remember this file in auto generated and you should not modify it directly until a dependency change. To suggest changes please submit pull request to the relevant dependency.
- command: diff --unified --color stackgl_modules/INDEX.js stackgl_modules/index.js
- - store_artifacts:
- path: stackgl_modules/index.js
- destination: stackgl_modules/index.js
-
- test-topojson-build:
- docker:
- - image: cimg/node:18.20.4
- working_directory: ~/plotly.js
- steps:
- - checkout
- - run:
- name: Set up build environment
- command: cd topojson && npm ci
- - run:
- name: Build topojson
- command: cd topojson && mv dist dist_backup && npm run build
- - run:
- name: Compare existing files with newly built files. Any difference is a failure. A failure might mean that the source data changed.
- command: diff -qr topojson/dist topojson/dist_backup
- - run:
- name: Compress artifacts
- command: tar -cvzf topojson.tar topojson/dist
- - store_artifacts:
- path: topojson.tar
-
-commands:
- image-diff-message:
- steps:
- - run:
- name: IMAGE DIFF DETECTED - SEE NOTE BELOW
- when: on_fail
- command: |
- echo "Image Diff Detected: baseline images may need to be updated. Run 'tasks/circleci_image_artifact_download.sh' to download the baseline images generated by this job."
- echo "Add the new images to 'test/image/baselines/' and commit them to this pull request."
-
-workflows:
- version: 2
- build-and-test:
- max_auto_reruns: 1
- jobs:
- - install-and-cibuild
- - timezone-jasmine:
- requires:
- - install-and-cibuild
- - bundle-jasmine:
- requires:
- - install-and-cibuild
- - mathjax-firefoxLatest:
- requires:
- - install-and-cibuild
- - no-gl-jasmine:
- requires:
- - install-and-cibuild
- - webgl-jasmine:
- requires:
- - install-and-cibuild
- - virtual-webgl-jasmine:
- requires:
- - install-and-cibuild
- - webgl-jasmine-chromeLatest:
- requires:
- - install-and-cibuild
- - flaky-no-gl-jasmine:
- requires:
- - install-and-cibuild
- - make-baselines-virtual-webgl:
- requires:
- - install-and-cibuild
- - test-baselines-virtual-webgl:
- requires:
- - make-baselines-virtual-webgl
- - make-baselines-mathjax3:
- requires:
- - install-and-cibuild
- - test-baselines-mathjax3:
- requires:
- - make-baselines-mathjax3
- - make-baselines-b64:
- requires:
- - install-and-cibuild
- - test-baselines-b64:
- requires:
- - make-baselines-b64
- - make-baselines:
- requires:
- - install-and-cibuild
- - test-baselines:
- requires:
- - make-baselines
- - make-exports:
- requires:
- - install-and-cibuild
- - test-exports:
- requires:
- - make-exports
- - mock-validation:
- requires:
- - install-and-cibuild
- - source-syntax:
- requires:
- - install-and-cibuild
-
- - publish-dist
-
- - publish-dist-node-v22
-
- - test-stackgl-bundle
-
- - test-topojson-build
diff --git a/.circleci/download_google_fonts.py b/.circleci/download_google_fonts.py
deleted file mode 100644
index 8dc9dd7daa6..00000000000
--- a/.circleci/download_google_fonts.py
+++ /dev/null
@@ -1,82 +0,0 @@
-import os
-
-import requests
-
-dir_out = ".circleci/fonts/truetype/googleFonts/"
-
-
-def download(repo, family, types, overwrite=True):
- for t in types:
- name = family + t + ".ttf"
- url = repo + name + "?raw=true"
- out_file = dir_out + name
- print("Getting: ", url)
- if os.path.exists(out_file) and not overwrite:
- print(" => Already exists: ", out_file)
- continue
- req = requests.get(url, allow_redirects=False)
- if req.status_code != 200:
- # If we get a redirect, print an error so that we know to update the URL
- if req.status_code == 302 or req.status_code == 301:
- new_url = req.headers.get("Location")
- print(f" => Redirected -- please update URL to: {new_url}")
- raise RuntimeError(f"""
-Download failed.
-Status code: {req.status_code}
-Message: {req.reason}
-""")
- open(out_file, "wb").write(req.content)
-
-
-download(
- "https://cdn.jsdelivr.net/gh/notofonts/notofonts.github.io/fonts/NotoSansMono/hinted/ttf/",
- "NotoSansMono",
- ["-Regular", "-Bold"],
-)
-
-download(
- "https://cdn.jsdelivr.net/gh/notofonts/notofonts.github.io/fonts/NotoSans/hinted/ttf/",
- "NotoSans",
- ["-Regular", "-Italic", "-Bold"],
-)
-
-download(
- "https://cdn.jsdelivr.net/gh/notofonts/notofonts.github.io/fonts/NotoSerif/hinted/ttf/",
- "NotoSerif",
- [
- "-Regular",
- "-Italic",
- "-Bold",
- "-BoldItalic",
- ],
-)
-
-download(
- "https://raw.githubusercontent.com/google/fonts/refs/heads/main/ofl/oldstandardtt/",
- "OldStandard",
- ["-Regular", "-Italic", "-Bold"],
-)
-
-download(
- "https://raw.githubusercontent.com/google/fonts/refs/heads/main/ofl/ptsansnarrow/",
- "PT_Sans-Narrow-Web",
- ["-Regular", "-Bold"],
-)
-
-download(
- "https://raw.githubusercontent.com/impallari/Raleway/refs/heads/master/fonts/v3.000%20Fontlab/TTF/",
- "Raleway",
- ["-Regular", "-Regular-Italic", "-Bold", "-Bold-Italic"],
-)
-
-download(
- "https://raw.githubusercontent.com/googlefonts/roboto-2/refs/heads/main/src/hinted/",
- "Roboto",
- ["-Regular", "-Italic", "-Bold", "-BoldItalic"],
-)
-
-download(
- "https://raw.githubusercontent.com/expo/google-fonts/refs/heads/main/font-packages/gravitas-one/400Regular/",
- "GravitasOne",
- ["_400Regular"],
-)
diff --git a/.circleci/env_image.sh b/.circleci/env_image.sh
deleted file mode 100755
index 17e2f5bfa26..00000000000
--- a/.circleci/env_image.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-set -e
-# install required fonts
-sudo apt-get install fonts-liberation2 fonts-open-sans fonts-noto-cjk fonts-noto-color-emoji
-
-# install pip
-sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
-sudo python3 get-pip.py
-
-# install additional fonts
-sudo python3 -m pip install requests
-sudo python3 .circleci/download_google_fonts.py
-sudo cp -r .circleci/fonts/ /usr/share/
-sudo apt install fontconfig
-sudo fc-cache -f
-
-# install kaleido & plotly
-sudo python3 -m pip install kaleido==0.2.1 plotly==6.2.0 --progress-bar off
-
-# install numpy i.e. to convert arrays to typed arrays
-sudo python3 -m pip install numpy==1.24.2
diff --git a/.github/actions/run-xvfb/action.yml b/.github/actions/run-xvfb/action.yml
new file mode 100644
index 00000000000..36b2d96fcfc
--- /dev/null
+++ b/.github/actions/run-xvfb/action.yml
@@ -0,0 +1,13 @@
+name: 'Run with Xvfb'
+description: 'Run a command under Xvfb with a preconfigured screen size'
+
+inputs:
+ run:
+ description: 'Command to execute'
+ required: true
+
+runs:
+ using: 'composite'
+ steps:
+ - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x1024x24" ${{ inputs.run }}
+ shell: bash
diff --git a/.github/actions/setup-chrome/action.yml b/.github/actions/setup-chrome/action.yml
new file mode 100644
index 00000000000..13b9f1a3f33
--- /dev/null
+++ b/.github/actions/setup-chrome/action.yml
@@ -0,0 +1,25 @@
+name: 'Setup Chrome'
+description: 'Install Chrome and set CHROME_BIN environment variable'
+
+inputs:
+ chrome-version:
+ description: 'Chrome version to install'
+ default: '136.0.7103.113'
+
+runs:
+ using: 'composite'
+ steps:
+ - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2
+ id: setup-chrome
+ with:
+ chrome-version: ${{ inputs.chrome-version }}
+
+ - name: Set Chrome binary path
+ run: echo "CHROME_BIN=${{ steps.setup-chrome.outputs.chrome-path }}" >> $GITHUB_ENV
+ shell: bash
+
+ - name: Verify Chrome version
+ run: |
+ echo "Chrome path: $CHROME_BIN"
+ $CHROME_BIN --version
+ shell: bash
diff --git a/.github/actions/setup-image-env/action.yml b/.github/actions/setup-image-env/action.yml
new file mode 100644
index 00000000000..c319b2eff53
--- /dev/null
+++ b/.github/actions/setup-image-env/action.yml
@@ -0,0 +1,35 @@
+name: 'Setup Image Environment'
+description: 'Setup Python, uv, and install Kaleido/plotly with required fonts'
+
+inputs:
+ python-version:
+ description: 'Python version to use'
+ default: '3.12'
+ uv-version:
+ description: 'uv version to use'
+ default: '0.11.2'
+
+runs:
+ using: 'composite'
+ steps:
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
+ with:
+ python-version: ${{ inputs.python-version }}
+
+ - name: Install uv
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
+ with:
+ version: ${{ inputs.uv-version }}
+
+ - name: Cache apt font packages
+ uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
+ id: apt-cache
+ with:
+ path: ~/.cache/apt-fonts
+ key: apt-fonts-${{ runner.os }}-${{ hashFiles('.github/scripts/env_image.sh') }}
+
+ - name: Install Kaleido, plotly.io and required fonts
+ run: .github/scripts/env_image.sh
+ shell: bash
+ env:
+ APT_CACHE_HIT: ${{ steps.apt-cache.outputs.cache-hit }}
diff --git a/.github/actions/setup-workspace/action.yml b/.github/actions/setup-workspace/action.yml
new file mode 100644
index 00000000000..c2e39d0f41b
--- /dev/null
+++ b/.github/actions/setup-workspace/action.yml
@@ -0,0 +1,26 @@
+name: 'Setup Workspace'
+description: 'Setup Node.js, install dependencies, and download build artifacts'
+
+inputs:
+ node-version:
+ description: 'Node.js version to use'
+ default: '18'
+
+runs:
+ using: 'composite'
+ steps:
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
+ with:
+ node-version: ${{ inputs.node-version }}
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+ shell: bash
+ env:
+ NODE_OPTIONS: '--max-old-space-size=4096'
+
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
+ with:
+ name: build-output
+ path: .
diff --git a/.circleci/fonts/truetype/googleFonts/GravitasOne_400Regular.ttf b/.github/fonts/truetype/googleFonts/GravitasOne_400Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/GravitasOne_400Regular.ttf
rename to .github/fonts/truetype/googleFonts/GravitasOne_400Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSans-Bold.ttf b/.github/fonts/truetype/googleFonts/NotoSans-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSans-Bold.ttf
rename to .github/fonts/truetype/googleFonts/NotoSans-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSans-Italic.ttf b/.github/fonts/truetype/googleFonts/NotoSans-Italic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSans-Italic.ttf
rename to .github/fonts/truetype/googleFonts/NotoSans-Italic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSans-Regular.ttf b/.github/fonts/truetype/googleFonts/NotoSans-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSans-Regular.ttf
rename to .github/fonts/truetype/googleFonts/NotoSans-Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSansMono-Bold.ttf b/.github/fonts/truetype/googleFonts/NotoSansMono-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSansMono-Bold.ttf
rename to .github/fonts/truetype/googleFonts/NotoSansMono-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSansMono-Regular.ttf b/.github/fonts/truetype/googleFonts/NotoSansMono-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSansMono-Regular.ttf
rename to .github/fonts/truetype/googleFonts/NotoSansMono-Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSerif-Bold.ttf b/.github/fonts/truetype/googleFonts/NotoSerif-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSerif-Bold.ttf
rename to .github/fonts/truetype/googleFonts/NotoSerif-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSerif-BoldItalic.ttf b/.github/fonts/truetype/googleFonts/NotoSerif-BoldItalic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSerif-BoldItalic.ttf
rename to .github/fonts/truetype/googleFonts/NotoSerif-BoldItalic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSerif-Italic.ttf b/.github/fonts/truetype/googleFonts/NotoSerif-Italic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSerif-Italic.ttf
rename to .github/fonts/truetype/googleFonts/NotoSerif-Italic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/NotoSerif-Regular.ttf b/.github/fonts/truetype/googleFonts/NotoSerif-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/NotoSerif-Regular.ttf
rename to .github/fonts/truetype/googleFonts/NotoSerif-Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/OldStandard-Bold.ttf b/.github/fonts/truetype/googleFonts/OldStandard-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/OldStandard-Bold.ttf
rename to .github/fonts/truetype/googleFonts/OldStandard-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/OldStandard-Italic.ttf b/.github/fonts/truetype/googleFonts/OldStandard-Italic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/OldStandard-Italic.ttf
rename to .github/fonts/truetype/googleFonts/OldStandard-Italic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/OldStandard-Regular.ttf b/.github/fonts/truetype/googleFonts/OldStandard-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/OldStandard-Regular.ttf
rename to .github/fonts/truetype/googleFonts/OldStandard-Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Bold.ttf b/.github/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Bold.ttf
rename to .github/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Regular.ttf b/.github/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Regular.ttf
rename to .github/fonts/truetype/googleFonts/PT_Sans-Narrow-Web-Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Raleway-Bold-Italic.ttf b/.github/fonts/truetype/googleFonts/Raleway-Bold-Italic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Raleway-Bold-Italic.ttf
rename to .github/fonts/truetype/googleFonts/Raleway-Bold-Italic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Raleway-Bold.ttf b/.github/fonts/truetype/googleFonts/Raleway-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Raleway-Bold.ttf
rename to .github/fonts/truetype/googleFonts/Raleway-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Raleway-Regular-Italic.ttf b/.github/fonts/truetype/googleFonts/Raleway-Regular-Italic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Raleway-Regular-Italic.ttf
rename to .github/fonts/truetype/googleFonts/Raleway-Regular-Italic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Raleway-Regular.ttf b/.github/fonts/truetype/googleFonts/Raleway-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Raleway-Regular.ttf
rename to .github/fonts/truetype/googleFonts/Raleway-Regular.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Roboto-Bold.ttf b/.github/fonts/truetype/googleFonts/Roboto-Bold.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Roboto-Bold.ttf
rename to .github/fonts/truetype/googleFonts/Roboto-Bold.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Roboto-BoldItalic.ttf b/.github/fonts/truetype/googleFonts/Roboto-BoldItalic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Roboto-BoldItalic.ttf
rename to .github/fonts/truetype/googleFonts/Roboto-BoldItalic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Roboto-Italic.ttf b/.github/fonts/truetype/googleFonts/Roboto-Italic.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Roboto-Italic.ttf
rename to .github/fonts/truetype/googleFonts/Roboto-Italic.ttf
diff --git a/.circleci/fonts/truetype/googleFonts/Roboto-Regular.ttf b/.github/fonts/truetype/googleFonts/Roboto-Regular.ttf
similarity index 100%
rename from .circleci/fonts/truetype/googleFonts/Roboto-Regular.ttf
rename to .github/fonts/truetype/googleFonts/Roboto-Regular.ttf
diff --git a/.circleci/env_build.sh b/.github/scripts/env_build.sh
similarity index 100%
rename from .circleci/env_build.sh
rename to .github/scripts/env_build.sh
diff --git a/.github/scripts/env_image.sh b/.github/scripts/env_image.sh
new file mode 100755
index 00000000000..6eca8bbcd2c
--- /dev/null
+++ b/.github/scripts/env_image.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+set -e
+
+APT_PACKAGES="fonts-liberation2 fonts-open-sans fonts-noto-cjk fonts-noto-color-emoji fontconfig"
+APT_CACHE_DIR="${HOME}/.cache/apt-fonts"
+
+if [ "$APT_CACHE_HIT" = "true" ] && [ -d "$APT_CACHE_DIR" ]; then
+ echo "Installing font packages from cache..."
+ sudo dpkg -i "$APT_CACHE_DIR"/*.deb 2>/dev/null || sudo apt-get install -yf
+else
+ echo "Downloading and installing font packages..."
+ sudo apt-get update -q
+ sudo apt-get install -y --no-install-recommends $APT_PACKAGES
+ # Save debs for future cache
+ mkdir -p "$APT_CACHE_DIR"
+ for pkg in $APT_PACKAGES; do
+ cp /var/cache/apt/archives/${pkg}_*.deb "$APT_CACHE_DIR/" 2>/dev/null || true
+ done
+fi
+
+# Rebuild font cache
+sudo fc-cache -f
+
+# Install additional fonts (committed in .github/fonts/)
+sudo cp -r .github/fonts/ /usr/share/
+sudo fc-cache -f
+
+# Install Kaleido & Plotly
+uv pip install --system kaleido==0.2.1 plotly==6.6.0 --no-progress
+
+# Install numpy i.e. to convert arrays to typed arrays
+uv pip install --system numpy==2.4.3
+
+# Verify version of python and versions of installed python packages
+python --version
+uv pip freeze --system
diff --git a/.github/scripts/split_files.mjs b/.github/scripts/split_files.mjs
new file mode 100755
index 00000000000..51e9a3562a9
--- /dev/null
+++ b/.github/scripts/split_files.mjs
@@ -0,0 +1,19 @@
+#!/usr/bin/env node
+
+// Reads lines from stdin and emits only those where index % SHARD_TOTAL == SHARD_INDEX
+// Environment variables SHARD_INDEX and SHARD_TOTAL must be set.
+
+import { readFileSync } from 'fs';
+
+const lines = readFileSync('/dev/stdin', 'utf8').trim().split('\n').filter(Boolean);
+const index = parseInt(process.env.SHARD_INDEX);
+const total = parseInt(process.env.SHARD_TOTAL);
+
+if (isNaN(index) || isNaN(total) || total <= 0) {
+ console.error('SHARD_INDEX and SHARD_TOTAL environment variables must be set to valid integers');
+ process.exit(1);
+}
+
+lines.forEach((line, i) => {
+ if (i % total === index) console.log(line);
+});
diff --git a/.circleci/test.sh b/.github/scripts/test.sh
similarity index 71%
rename from .circleci/test.sh
rename to .github/scripts/test.sh
index 4fc876018b8..7bd42ff6feb 100755
--- a/.circleci/test.sh
+++ b/.github/scripts/test.sh
@@ -1,10 +1,13 @@
#!/bin/bash
-# override CircleCi's default run settings
+# GitHub Actions version of .circleci/test.sh
+# Replaces `circleci tests split` with split_files.mjs
+
set +e
set +o pipefail
-ROOT=$(dirname $0)/..
+ROOT=$(dirname $0)/../..
+SPLIT="$ROOT/.github/scripts/split_files.mjs"
EXIT_STATE=0
MAX_AUTO_RETRY=0
@@ -33,10 +36,13 @@ retry () {
fi
}
+# Ensure output directories exist (not present in fresh GHA checkout)
+mkdir -p build/test_images
+
case $1 in
no-gl-jasmine)
- SUITE=$(circleci tests glob "$ROOT/test/jasmine/tests/*" | circleci tests split)
+ SUITE=$(ls -1 $ROOT/test/jasmine/tests/* | sort | node "$SPLIT")
MAX_AUTO_RETRY=2
retry npm run test-jasmine -- $SUITE --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
@@ -44,7 +50,7 @@ case $1 in
;;
webgl-jasmine)
- SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | circleci tests split))
+ SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | node "$SPLIT"))
for s in ${SHARDS[@]}; do
MAX_AUTO_RETRY=2
retry npm run test-jasmine -- "$s" --tags=gl --skip-tags=noCI --doNotFailOnEmptyTestSuite
@@ -54,7 +60,7 @@ case $1 in
;;
virtual-webgl-jasmine)
- SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | circleci tests split))
+ SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=5 --tag=gl | node "$SPLIT"))
for s in ${SHARDS[@]}; do
MAX_AUTO_RETRY=2
retry ./node_modules/karma/bin/karma start test/jasmine/karma.conf.js --virtualWebgl --tags=gl --skip-tags=noCI,noVirtualWebgl --doNotFailOnEmptyTestSuite -- "$s"
@@ -64,7 +70,7 @@ case $1 in
;;
flaky-no-gl-jasmine)
- SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=1 --tag=flaky | circleci tests split))
+ SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=1 --tag=flaky | node "$SPLIT"))
for s in ${SHARDS[@]}; do
MAX_AUTO_RETRY=5
@@ -96,40 +102,46 @@ case $1 in
SUITE=$({\
find $ROOT/test/image/mocks/gl* -type f -printf "%f\n"; \
find $ROOT/test/image/mocks/map* -type f -printf "%f\n"; \
- } | sed 's/\.json$//1' | circleci tests split)
- sudo python3 test/image/make_baseline.py virtual-webgl $SUITE || EXIT_STATE=$?
+ } | sed 's/\.json$//1' | sort | node "$SPLIT")
+ python test/image/make_baseline.py virtual-webgl $SUITE || EXIT_STATE=$?
exit $EXIT_STATE
;;
make-baselines-mathjax3)
- sudo python3 test/image/make_baseline.py mathjax3 legend_mathjax_title_and_items mathjax parcats_grid_subplots table_latex_multitrace_scatter table_plain_birds table_wrapped_birds ternary-mathjax ternary-mathjax-title-place-subtitle || EXIT_STATE=$?
+ MATHJAX3_MOCKS=$(jq -r '.compare_mathjax3 | join(" ")' test/image/compare_pixels_collections.json)
+ python test/image/make_baseline.py mathjax3 $MATHJAX3_MOCKS || EXIT_STATE=$?
exit $EXIT_STATE
;;
make-baselines-b64)
- SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | circleci tests split)
- sudo python3 test/image/make_baseline.py b64 $SUITE || EXIT_STATE=$?
+ SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | sort | node "$SPLIT")
+ python test/image/make_baseline.py b64 $SUITE || EXIT_STATE=$?
exit $EXIT_STATE
;;
make-baselines)
- SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | circleci tests split)
- sudo python3 test/image/make_baseline.py $SUITE || EXIT_STATE=$?
+ SUITE=$(find $ROOT/test/image/mocks/ -type f -printf "%f\n" | sed 's/\.json$//1' | sort | node "$SPLIT")
+ python test/image/make_baseline.py $SUITE || EXIT_STATE=$?
+ exit $EXIT_STATE
+ ;;
+
+ make-exports)
+ python test/image/make_exports.py || EXIT_STATE=$?
exit $EXIT_STATE
;;
test-image)
- node test/image/compare_pixels_test.js || { tar -cvf build/baselines.tar build/test_images/*.png ; exit 1 ; } || EXIT_STATE=$?
+ node test/image/compare_pixels_test.mjs || EXIT_STATE=$?
exit $EXIT_STATE
;;
test-image-mathjax3)
- node test/image/compare_pixels_test.js mathjax3 || { tar -cvf build/baselines.tar build/test_images/*.png ; exit 1 ; } || EXIT_STATE=$?
+ node test/image/compare_pixels_test.mjs mathjax3 || EXIT_STATE=$?
exit $EXIT_STATE
;;
test-image-virtual-webgl)
- node test/image/compare_pixels_test.js virtual-webgl || { tar -cvf build/baselines.tar build/test_images/*.png ; exit 1 ; } || EXIT_STATE=$?
+ node test/image/compare_pixels_test.mjs virtual-webgl || EXIT_STATE=$?
exit $EXIT_STATE
;;
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000000..9002158c911
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,715 @@
+name: CI
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ types:
+ - opened
+ - reopened
+ - synchronize
+ workflow_dispatch:
+
+concurrency:
+ group: ci-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
+env:
+ NODE_VERSION: '18'
+
+jobs:
+ # ============================================================
+ # Root build job - all dependent jobs fan out from here
+ # ============================================================
+ install-and-cibuild:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+ env:
+ NODE_OPTIONS: '--max-old-space-size=4096'
+
+ - name: Pretest
+ run: npm run pretest
+
+ - name: CI-Build
+ run: npm run cibuild
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: build-output
+ retention-days: 3
+ path: |
+ build/
+ lib/
+ src/version.js
+
+ # ============================================================
+ # Jasmine browser tests
+ # ============================================================
+ timezone-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+
+ - name: Run hover_label test in UTC timezone
+ uses: ./.github/actions/run-xvfb
+ env:
+ TZ: 'UTC'
+ with:
+ run: npm run test-jasmine hover_label
+
+ - name: Run hover_label test in Europe/Berlin timezone
+ uses: ./.github/actions/run-xvfb
+ env:
+ TZ: 'Europe/Berlin'
+ with:
+ run: npm run test-jasmine hover_label
+
+ - name: Run hover_label test in Asia/Tokyo timezone
+ uses: ./.github/actions/run-xvfb
+ env:
+ TZ: 'Asia/Tokyo'
+ with:
+ run: npm run test-jasmine hover_label
+
+ - name: Run hover_label test in America/Toronto timezone
+ uses: ./.github/actions/run-xvfb
+ env:
+ TZ: 'America/Toronto'
+ with:
+ run: npm run test-jasmine hover_label
+
+ no-gl-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3]
+ env:
+ TZ: 'America/Anchorage'
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 4
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+
+ - name: Run jasmine tests (no-gl, shard ${{ matrix.shard }})
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh no-gl-jasmine
+
+ webgl-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3, 4, 5, 6, 7]
+ env:
+ TZ: 'America/Anchorage'
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 8
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+
+ - name: Run jasmine tests (webgl, shard ${{ matrix.shard }})
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh webgl-jasmine
+
+ virtual-webgl-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3, 4, 5, 6, 7]
+ env:
+ TZ: 'America/Anchorage'
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 8
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+
+ - name: Run jasmine tests (virtual-webgl, shard ${{ matrix.shard }})
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh virtual-webgl-jasmine
+
+ webgl-jasmine-chromeLatest:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3, 4, 5, 6, 7]
+ env:
+ TZ: 'America/Anchorage'
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 8
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+ with:
+ chrome-version: '143.0.7499.192'
+
+ - name: Run jasmine tests (webgl chromeLatest, shard ${{ matrix.shard }})
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh webgl-jasmine
+
+ flaky-no-gl-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ env:
+ TZ: 'America/Anchorage'
+ SHARD_INDEX: 0
+ SHARD_TOTAL: 1
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+
+ - name: Run flaky jasmine tests
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh flaky-no-gl-jasmine
+
+ bundle-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ env:
+ TZ: 'America/Anchorage'
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+
+ - name: Run bundle jasmine tests
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh bundle-jasmine
+
+ mathjax-firefoxLatest:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ env:
+ TZ: 'America/Anchorage'
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: browser-actions/setup-firefox@fcf821c621167805dd63a29662bd7cb5676c81a8 # v1
+
+ - name: Test MathJax on firefox-latest
+ uses: ./.github/actions/run-xvfb
+ with:
+ run: .github/scripts/test.sh mathjax-firefox
+
+ # ============================================================
+ # noCI tests
+ # ============================================================
+ noci-jasmine:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+ - uses: ./.github/actions/setup-chrome
+ with:
+ chrome-version: 'stable'
+
+ - name: Run noCI tests
+ uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
+ with:
+ run: ./tasks/noci_test.sh jasmine
+
+ # ============================================================
+ # Image baseline generation and comparison
+ # ============================================================
+ make-baselines:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
+ env:
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 12
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: ./.github/actions/setup-image-env
+
+ - name: Create all png files
+ run: .github/scripts/test.sh make-baselines
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: baselines-default-${{ matrix.shard }}
+ retention-days: 3
+ path: build/test_images/
+
+ test-baselines:
+ needs: make-baselines
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
+ with:
+ pattern: baselines-default-*
+ path: build/test_images/
+ merge-multiple: true
+
+ - name: Compare pixels
+ run: .github/scripts/test.sh test-image
+ - name: List diff folder contents
+ if: failure()
+ run: |
+ echo "=== build/test_images/ ==="
+ ls -la build/test_images/ 2>/dev/null || echo "(empty or missing)"
+ echo "=== build/test_images_diff/ ==="
+ ls -la build/test_images_diff/ 2>/dev/null || echo "(empty or missing)"
+ - name: IMAGE DIFF DETECTED
+ if: failure()
+ run: |
+ echo "::warning::Image Diff Detected: baseline images may need to be updated."
+ echo "Download the baseline images from the artifacts of this workflow run."
+ echo "Add the new images to 'test/image/baselines/' and commit them to this pull request."
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: baselines-default-diff
+ retention-days: 7
+ path: |
+ build/test_images/
+ build/test_images_diff/
+
+ make-baselines-b64:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
+ env:
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 12
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: ./.github/actions/setup-image-env
+
+ - name: Create all png files (b64)
+ run: .github/scripts/test.sh make-baselines-b64
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: baselines-b64-${{ matrix.shard }}
+ retention-days: 3
+ path: build/test_images/
+
+ test-baselines-b64:
+ needs: make-baselines-b64
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
+ with:
+ pattern: baselines-b64-*
+ path: build/test_images/
+ merge-multiple: true
+
+ - name: Compare pixels
+ run: .github/scripts/test.sh test-image
+ - name: IMAGE DIFF DETECTED
+ if: failure()
+ run: |
+ echo "::warning::Image Diff Detected: baseline images may need to be updated."
+ echo "Download the baseline images from the artifacts of this workflow run."
+ echo "Add the new images to 'test/image/baselines/' and commit them to this pull request."
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: baselines-b64-diff
+ retention-days: 7
+ path: |
+ build/test_images/
+ build/test_images_diff/
+
+ make-baselines-virtual-webgl:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ shard: [0, 1, 2, 3, 4, 5, 6, 7]
+ env:
+ SHARD_INDEX: ${{ matrix.shard }}
+ SHARD_TOTAL: 8
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: ./.github/actions/setup-image-env
+
+ - name: Create png files (virtual-webgl)
+ run: .github/scripts/test.sh make-baselines-virtual-webgl
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: baselines-virtual-webgl-${{ matrix.shard }}
+ retention-days: 3
+ path: build/test_images/
+
+ test-baselines-virtual-webgl:
+ needs: make-baselines-virtual-webgl
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
+ with:
+ pattern: baselines-virtual-webgl-*
+ path: build/test_images/
+ merge-multiple: true
+
+ - name: Compare pixels
+ run: .github/scripts/test.sh test-image-virtual-webgl
+ - name: IMAGE DIFF DETECTED
+ if: failure()
+ run: |
+ echo "::warning::Image Diff Detected: baseline images may need to be updated."
+ echo "Download the baseline images from the artifacts of this workflow run."
+ echo "Add the new images to 'test/image/baselines/' and commit them to this pull request."
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: baselines-virtual-webgl-diff
+ retention-days: 7
+ path: |
+ build/test_images/
+ build/test_images_diff/
+
+ make-baselines-mathjax3:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: ./.github/actions/setup-image-env
+
+ - name: Create mathjax v3 png files
+ run: .github/scripts/test.sh make-baselines-mathjax3
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: baselines-mathjax3
+ retention-days: 3
+ path: build/test_images/
+
+ test-baselines-mathjax3:
+ needs: make-baselines-mathjax3
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
+ with:
+ name: baselines-mathjax3
+ path: build/test_images/
+
+ - name: Compare pixels of mathjax v3 baselines
+ run: .github/scripts/test.sh test-image-mathjax3
+
+ - name: IMAGE DIFF DETECTED
+ if: failure()
+ run: |
+ echo "::warning::Image Diff Detected: baseline images may need to be updated."
+ echo "Download the baseline images from the artifacts of this workflow run."
+ echo "Add the new images to 'test/image/baselines/' and commit them to this pull request."
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: baselines-mathjax3-diff
+ retention-days: 7
+ path: |
+ build/test_images/
+ build/test_images_diff/
+
+ # ============================================================
+ # Export generation and testing
+ # ============================================================
+ make-exports:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: ./.github/actions/setup-image-env
+
+ - name: Install poppler-utils for eps export
+ run: |
+ sudo apt-get update --allow-releaseinfo-change
+ sudo apt-get install poppler-utils
+
+ - name: Create svg, jpg, jpeg, webp, pdf and eps files
+ run: .github/scripts/test.sh make-exports
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: exports
+ retention-days: 3
+ path: build/
+
+ test-exports:
+ needs: make-exports
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
+ with:
+ name: exports
+ path: build/
+
+ - name: Test export sizes
+ run: node test/image/export_test.js
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: exports-diff
+ retention-days: 7
+ path: build/
+
+ # ============================================================
+ # Validation jobs
+ # ============================================================
+ mock-validation:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - name: Test validation using node.js and jsdom
+ run: npm run test-plain-obj
+
+ - name: Validate mocks
+ run: npm run test-mock
+
+ source-syntax:
+ needs: install-and-cibuild
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ - uses: ./.github/actions/setup-workspace
+
+ - name: Run syntax tests on source files
+ run: .github/scripts/test.sh source-syntax
+
+ # ============================================================
+ # Standalone jobs (no dependencies on install-and-cibuild)
+ # ============================================================
+ publish-dist:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+ fetch-tags: true
+
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: 'npm'
+
+ - name: Set up build environment
+ run: .github/scripts/env_build.sh
+
+ - name: Preview CHANGELOG for next release (only on master)
+ if: github.ref == 'refs/heads/master'
+ run: npm run use-draftlogs && git --no-pager diff --color-words CHANGELOG.md || true
+
+ - name: Set draft version in package.json
+ run: |
+ node --eval "var fs = require('fs'); var inOut = './package.json'; var data = JSON.parse(fs.readFileSync(inOut)); var a = process.argv; data.version = a[a.length - 1].replace('v', ''); fs.writeFileSync(inOut, JSON.stringify(data, null, 2) + '\n');" $(git describe)
+
+ - name: View package.json diff between previous and next releases
+ run: git --no-pager diff --color-words tags/$(git describe --tags --abbrev=0) package.json || true
+
+ - name: Build dist/
+ run: npm run build
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: dist-node18
+ retention-days: 7
+ path: dist/
+
+ - name: View dist/README.md diff between previous and next releases
+ run: git --no-pager diff --color-words tags/$(git describe --tags --abbrev=0) dist/README.md || true
+
+ - name: Preview plot-schema diff (only on master)
+ if: github.ref == 'refs/heads/master'
+ run: git --no-pager diff tags/$(git describe --tags --abbrev=0) dist/plot-schema.json || true
+
+ - name: Pack tarball
+ run: |
+ npm pack
+ version=$(node --eval "console.log(require('./package.json').version)")
+ mv plotly.js-$version.tgz plotly.js.tgz
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: tarball-node18
+ retention-days: 7
+ path: plotly.js.tgz
+
+ - name: Test plot-schema.json diff
+ run: diff --unified --color dist/plot-schema.json test/plot-schema.json
+
+ publish-dist-node-v22:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+ fetch-tags: true
+
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
+ with:
+ node-version: '22.14.0'
+ cache: 'npm'
+
+ - name: Set up build environment
+ run: .github/scripts/env_build.sh
+
+ - name: Preview CHANGELOG for next release (only on master)
+ if: github.ref == 'refs/heads/master'
+ run: npm run use-draftlogs && git --no-pager diff --color-words CHANGELOG.md || true
+
+ - name: Set draft version in package.json
+ run: |
+ node --eval "var fs = require('fs'); var inOut = './package.json'; var data = JSON.parse(fs.readFileSync(inOut)); var a = process.argv; data.version = a[a.length - 1].replace('v', ''); fs.writeFileSync(inOut, JSON.stringify(data, null, 2) + '\n');" $(git describe)
+
+ - name: View package.json diff between previous and next releases
+ run: git --no-pager diff --color-words tags/$(git describe --tags --abbrev=0) package.json || true
+
+ - name: Build dist/
+ run: npm run build
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: dist-node22
+ retention-days: 7
+ path: dist/
+
+ - name: View dist/README.md diff between previous and next releases
+ run: git --no-pager diff --color-words tags/$(git describe --tags --abbrev=0) dist/README.md || true
+
+ - name: Preview plot-schema diff (only on master)
+ if: github.ref == 'refs/heads/master'
+ run: git --no-pager diff tags/$(git describe --tags --abbrev=0) dist/plot-schema.json || true
+
+ - name: Pack tarball
+ run: |
+ npm pack
+ version=$(node --eval "console.log(require('./package.json').version)")
+ mv plotly.js-$version.tgz plotly.js.tgz
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ with:
+ name: tarball-node22
+ retention-days: 7
+ path: plotly.js.tgz
+
+ - name: Test plot-schema.json diff
+ run: diff --unified --color dist/plot-schema.json test/plot-schema.json
+
+ test-stackgl-bundle:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: 'npm'
+
+ - name: Set up build environment
+ run: cd stackgl_modules && npm ci
+
+ - name: Bundle bundle-stackgl/index.js
+ run: cd stackgl_modules && cp index.js INDEX.js && npm run bundle-stackgl
+
+ - name: Test stackgl_modules/index.js diff
+ run: diff --unified --color stackgl_modules/INDEX.js stackgl_modules/index.js
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: stackgl-bundle
+ retention-days: 7
+ path: stackgl_modules/index.js
+
+ test-topojson-build:
+ if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: 'npm'
+
+ - name: Set up build environment
+ run: cd topojson && npm ci
+
+ - name: Build topojson
+ run: cd topojson && mv dist dist_backup && npm run build
+
+ - name: Compare existing files with newly built files
+ run: diff -qr topojson/dist topojson/dist_backup
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+ if: failure()
+ with:
+ name: topojson-dist
+ retention-days: 7
+ path: topojson/dist/
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index 93caad4a454..00000000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
-# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
-
-name: No CI Test
-
-on: push
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- node-version: [18.x]
-
- steps:
- - uses: browser-actions/setup-chrome@v2
- id: setup-chrome
- - uses: actions/checkout@v4
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v4
- with:
- node-version: ${{ matrix.node-version }}
- cache: 'npm'
- - name: Set Chrome binary path
- run: echo "CHROME_BIN=${{ steps.setup-chrome.outputs.chrome-path }}" >> $GITHUB_ENV
- - name: Verify Chrome version
- run: |
- echo "Chrome path: $CHROME_BIN"
- $CHROME_BIN --version
- - run: ls
- - run: npm run pretest
- - run: npm ci
- - run: npm run cibuild
- - name: Run noCI tests
- uses: coactions/setup-xvfb@v1
- with:
- run: ./tasks/noci_test.sh jasmine
diff --git a/biome.json b/biome.json
index 24635690072..b176cb37767 100644
--- a/biome.json
+++ b/biome.json
@@ -11,6 +11,7 @@
"**/tasks/**",
"**/devtools/**",
"**/topojson/**",
+ "**/.github/**",
"!**/test/plot-schema.json",
"!**/dist",
"!**/stackgl_modules",
diff --git a/package-lock.json b/package-lock.json
index 02fc4416104..dcb50905f38 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -104,7 +104,7 @@
"minify-stream": "^2.1.0",
"npm-link-check": "^5.0.1",
"open": "^8.4.2",
- "pixelmatch": "^5.3.0",
+ "pixelmatch": "^7.1.0",
"prepend-file": "^2.0.1",
"prettysize": "^2.0.0",
"raw-loader": "^4.0.2",
@@ -8208,12 +8208,13 @@
}
},
"node_modules/pixelmatch": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz",
- "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz",
+ "integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "pngjs": "^6.0.0"
+ "pngjs": "^7.0.0"
},
"bin": {
"pixelmatch": "bin/pixelmatch"
@@ -8229,12 +8230,13 @@
}
},
"node_modules/pngjs": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
- "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
+ "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=12.13.0"
+ "node": ">=14.19.0"
}
},
"node_modules/point-in-polygon": {
diff --git a/package.json b/package.json
index 04f32177e6e..1c8e1ed6fab 100644
--- a/package.json
+++ b/package.json
@@ -43,7 +43,7 @@
"pretest": "node tasks/pretest.js",
"test-jasmine": "karma start test/jasmine/karma.conf.js",
"test-mock": "node tasks/test_mock.mjs",
- "test-image": "node test/image/compare_pixels_test.js",
+ "test-image": "node test/image/compare_pixels_test.mjs",
"test-export": "node test/image/export_test.js",
"test-syntax": "node tasks/test_syntax.js && npm run find-strings -- --no-output",
"test-bundle": "node tasks/test_bundle.js",
@@ -162,7 +162,7 @@
"minify-stream": "^2.1.0",
"npm-link-check": "^5.0.1",
"open": "^8.4.2",
- "pixelmatch": "^5.3.0",
+ "pixelmatch": "^7.1.0",
"prepend-file": "^2.0.1",
"prettysize": "^2.0.0",
"raw-loader": "^4.0.2",
diff --git a/tasks/test_mock.mjs b/tasks/test_mock.mjs
index ae9bef8fcdd..2a69eaf7276 100644
--- a/tasks/test_mock.mjs
+++ b/tasks/test_mock.mjs
@@ -1,240 +1,246 @@
+import fs from 'fs';
import minimist from 'minimist';
+import os from 'os';
import path from 'path';
-import fs from 'fs';
+import { fileURLToPath } from 'url';
+import { isMainThread, parentPort, Worker, workerData } from 'worker_threads';
-import plotlyNode from './util/plotly_node.mjs';
-var Plotly = plotlyNode('build/plotly.js');
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const pathToRoot = path.join(__dirname, '..');
+const pathToMocks = path.join(pathToRoot, 'test', 'image', 'mocks');
-import { fileURLToPath } from 'url';
-var __dirname = path.dirname(fileURLToPath(import.meta.url));
+const disallowList = new Set([
+ // has contourcarpet See https://github.com/plotly/plotly.js/issues/5669
+ 'airfoil',
+ 'h-colorbar_airfoil',
+ 'cheater',
+ 'cheater_constraint_greater_than',
+ 'cheater_constraint_greater_than_with_hill',
+ 'cheater_constraint_greater_than_with_valley',
+ 'cheater_constraint_inner_range',
+ 'cheater_constraint_inner_range_hi_top',
+ 'cheater_constraint_inner_range_hi_top_with_hill',
+ 'cheater_constraint_inner_range_hi_top_with_valley',
+ 'cheater_constraint_inner_range_lo_top',
+ 'cheater_constraint_inner_range_lo_top_with_hill',
+ 'cheater_constraint_inner_range_lo_top_with_valley',
+ 'cheater_constraint_inner_range_with_hill',
+ 'cheater_constraint_inner_range_with_valley',
+ 'cheater_constraint_less_than',
+ 'cheater_constraint_less_than_with_hill',
+ 'cheater_constraint_less_than_with_valley',
+ 'cheater_constraint_outer_range',
+ 'cheater_constraint_outer_range_hi_top',
+ 'cheater_constraint_outer_range_hi_top_with_hill',
+ 'cheater_constraint_outer_range_hi_top_with_valley',
+ 'cheater_constraint_outer_range_lo_top',
+ 'cheater_constraint_outer_range_lo_top_with_hill',
+ 'cheater_constraint_outer_range_lo_top_with_valley',
+ 'cheater_constraint_outer_range_with_hill',
+ 'cheater_constraint_outer_range_with_valley',
+ 'cheater_constraints',
+ 'cheater_contour',
+ 'cheater_fully_filled',
+ 'cheater_smooth',
-var pathToRoot = path.join(__dirname, '..');
-var pathToMocks = path.join(pathToRoot, 'test', 'image', 'mocks');
+ // other
+ '1',
+ '11',
+ '12',
+ '13',
+ '14',
+ '15',
+ '16',
+ '17',
+ '18',
+ '19',
+ '21',
+ '22',
+ '23',
+ '24',
+ '25',
+ '26',
+ '27',
+ '28',
+ '29',
+ '30',
+ '31',
+ '32',
+ 'annotations',
+ 'annotations-autorange',
+ 'axes_labels',
+ 'candlestick_double-y-axis',
+ 'candlestick_rangeslider_thai',
+ 'category-autorange',
+ 'contour_match_edges',
+ 'dendrogram',
+ 'error_bar_style',
+ 'fake_violins',
+ 'fonts',
+ 'font-variant-bar',
+ 'font-weight-bar',
+ 'geo_africa-insets',
+ 'gl2d_10',
+ 'gl2d_12',
+ 'gl2d_14',
+ 'gl2d_17',
+ 'gl2d_annotations',
+ 'gl2d_axes_labels',
+ 'gl2d_fill_trace_tozero_order',
+ 'gl2d_fonts',
+ 'gl2d_layout_image',
+ 'gl2d_marker_coloraxis',
+ 'gl2d_rgb_dont_accept_alpha_scattergl',
+ 'gl2d_scatter-marker-line-colorscales',
+ 'gl2d_scatter-subplot-panel',
+ 'gl2d_shape_line',
+ 'gl2d_text_chart_basic',
+ 'gl2d_text_chart_single-string',
+ 'gl2d_text_chart_styling',
+ 'gl2d_texttemplate',
+ 'gl3d_bunny',
+ 'gl3d_bunny-hull',
+ 'gl3d_coloraxes',
+ 'gl3d_contour-lines',
+ 'gl3d_contour-lines2',
+ 'gl3d_convex-hull',
+ 'gl3d_cufflinks',
+ 'gl3d_directions-volume1',
+ 'gl3d_ibm-plot',
+ 'gl3d_line-colorscale-with-markers',
+ 'gl3d_opacity-surface',
+ 'gl3d_scatter-colorscale-marker',
+ 'gl3d_scatter3d-align-texts',
+ 'gl3d_surface_opacity-and-opacityscale',
+ 'gl3d_surface_opacityscale_contour',
+ 'gl3d_surface-heatmap-treemap_transparent-colorscale',
+ 'gl3d_surface-lighting',
+ 'gl3d_traces-with-legend',
+ 'gl3d_traces-with-opacity',
+ 'gl3d_volume_multiple-traces',
+ 'gl3d_z-range',
+ 'glpolar_scatter',
+ 'heatmap_small_aspect-ratio',
+ 'histogram_errorbars_inherit_color',
+ 'indicator_attrs',
+ 'indicator_bignumber',
+ 'indicator_bullet',
+ 'indicator_datacard',
+ 'indicator_datacard2',
+ 'indicator_gauge',
+ 'indicator_scatter',
+ 'japanese',
+ 'layout_image',
+ 'layout_metatext',
+ 'legend_horizontal',
+ 'legend_horizontal_autowrap',
+ 'legend-constant-itemsizing',
+ 'matching-missing-axes',
+ 'mathjax',
+ 'ohlc_first',
+ 'pattern_bars',
+ 'pattern_fgcolor_overlay_fillmode',
+ 'pattern_with_colorscale',
+ 'petrophysics',
+ 'plot_types',
+ 'polar_blank',
+ 'polar_dates',
+ 'range_slider_box',
+ 'shapes_fixed_size',
+ 'splom_ragged-via-axes',
+ 'stacked_area_duplicates',
+ 'table_plain_birds',
+ 'table_wrapped_birds',
+ 'text_chart_basic',
+ 'text_chart_single-string',
+ 'text_chart_styling',
+ 'texttemplate',
+ 'texttemplate_scatter',
+ 'titles-avoid-labels',
+ 'trace_metatext',
+ 'updatemenus',
+ 'violin_non-linear',
+ 'violin_ridgeplot',
+ 'violin_style',
+ 'waterfall_funnel_texttemplate_date',
+ 'yaxis-over-yaxis2',
+ 'yignbu_heatmap',
+ 'yiorrd_heatmap'
+]);
-var list = [];
+function validate(Plotly, name) {
+ const filename = path.join(pathToMocks, `${name}.json`);
+ const fig = JSON.parse(fs.readFileSync(filename));
+ const out = Plotly.validate(fig.data, fig.layout);
-// command line options
-var args = minimist(process.argv.slice(2), {});
-if(args._.length) {
- // test listed mock(s)
- list = args._;
-} else {
- // no mock listed, test all excluding the black list
- list = fs.readdirSync(pathToMocks)
- .filter(function(e) { return e.indexOf('.json') !== -1; })
- .map(function(e) { return e.replace('.json', ''); })
- .filter(notBlackListed);
+ if (!out) {
+ if (out !== undefined) {
+ console.error(`Expected ${out} to be undefined`);
+ return false;
+ }
+ return true;
+ }
+
+ for (const e of out) {
+ if (!['dynamic', 'invisible'].includes(e.code) && e.path.at(-1) !== 'coloraxis') {
+ console.error('Expected false to be true');
+ console.log('file:', name);
+ console.log(JSON.stringify(out, null, 2));
+ return false;
+ }
+ }
+ return true;
}
-var fail;
-var failedMocks = [];
+if (isMainThread) {
+ const args = minimist(process.argv.slice(2), {});
+ const list = args._.length
+ ? args._
+ : fs
+ .readdirSync(pathToMocks)
+ .filter((e) => e.endsWith('.json'))
+ .map((e) => e.replace('.json', ''))
+ .filter((e) => !disallowList.has(e));
-for(var i = 0; i < list.length; i++) {
- var name = list[i];
- console.log('validating ' + name);
+ const numWorkers = Math.min(args.workers || os.cpus().length, list.length);
+ const chunkSize = Math.ceil(list.length / numWorkers);
+ const promises = [];
- var filename = path.join(pathToMocks, name + '.json');
- var fig = JSON.parse(fs.readFileSync(filename));
- var out = Plotly.validate(fig.data, fig.layout);
+ console.log(`Validating ${list.length} mocks across ${numWorkers} workers...`);
- fail = false;
- assert(name, out);
- if(fail) failedMocks.push(name);
-}
+ for (let i = 0; i < numWorkers; i++) {
+ const chunk = list.slice(i * chunkSize, (i + 1) * chunkSize);
+ if (chunk.length === 0) continue;
-if(failedMocks.length) {
- var error = 'Failed at ' + JSON.stringify({mocks: failedMocks}, null, 2);
- throw error;
-}
+ promises.push(
+ new Promise((resolve, reject) => {
+ const worker = new Worker(new URL(import.meta.url), {
+ workerData: { mocks: chunk }
+ });
+ worker.on('message', resolve);
+ worker.on('error', reject);
+ })
+ );
+ }
+
+ const results = await Promise.all(promises);
+ const failedMocks = results.flat();
-function expectToBe(actual, expected) {
- if(actual !== expected) {
- console.error('Expected ' + actual + ' to be ' + expected);
- fail = true;
+ if (failedMocks.length) {
+ throw `Failed at ${JSON.stringify({ mocks: failedMocks }, null, 2)}`;
}
-}
-function assert(name, v) {
- var success = true;
- if(!v) {
- expectToBe(v, undefined);
- if(v !== undefined) success = false;
- } else {
- v.forEach(function(e) {
- var condition = (
- e.code === 'invisible' ||
- e.code === 'dynamic' ||
- e.path[e.path.length - 1] === 'coloraxis'
- );
- expectToBe(condition, true); // we accept invisible, dynamic and coloraxis for now
- if(!condition) {
- console.log('file:', name);
- console.log(JSON.stringify(v, null, 2));
- success = false;
- return success;
- }
- });
+ console.log('All mocks validated successfully.');
+} else {
+ const { default: plotlyNode } = await import('./util/plotly_node.mjs');
+ const Plotly = plotlyNode('build/plotly.js');
+ const { mocks } = workerData;
+ const failedMocks = [];
+
+ for (const name of mocks) {
+ console.log(`validating ${name}`);
+ if (!validate(Plotly, name)) failedMocks.push(name);
}
- return success;
-}
-function notBlackListed(name) {
- return [
- // has contourcarpet See https://github.com/plotly/plotly.js/issues/5669
- 'airfoil',
- 'h-colorbar_airfoil',
- 'cheater',
- 'cheater_constraint_greater_than',
- 'cheater_constraint_greater_than_with_hill',
- 'cheater_constraint_greater_than_with_valley',
- 'cheater_constraint_inner_range',
- 'cheater_constraint_inner_range_hi_top',
- 'cheater_constraint_inner_range_hi_top_with_hill',
- 'cheater_constraint_inner_range_hi_top_with_valley',
- 'cheater_constraint_inner_range_lo_top',
- 'cheater_constraint_inner_range_lo_top_with_hill',
- 'cheater_constraint_inner_range_lo_top_with_valley',
- 'cheater_constraint_inner_range_with_hill',
- 'cheater_constraint_inner_range_with_valley',
- 'cheater_constraint_less_than',
- 'cheater_constraint_less_than_with_hill',
- 'cheater_constraint_less_than_with_valley',
- 'cheater_constraint_outer_range',
- 'cheater_constraint_outer_range_hi_top',
- 'cheater_constraint_outer_range_hi_top_with_hill',
- 'cheater_constraint_outer_range_hi_top_with_valley',
- 'cheater_constraint_outer_range_lo_top',
- 'cheater_constraint_outer_range_lo_top_with_hill',
- 'cheater_constraint_outer_range_lo_top_with_valley',
- 'cheater_constraint_outer_range_with_hill',
- 'cheater_constraint_outer_range_with_valley',
- 'cheater_constraints',
- 'cheater_contour',
- 'cheater_fully_filled',
- 'cheater_smooth',
-
- // other
- '1',
- '11',
- '12',
- '13',
- '14',
- '15',
- '16',
- '17',
- '18',
- '19',
- '21',
- '22',
- '23',
- '24',
- '25',
- '26',
- '27',
- '28',
- '29',
- '30',
- '31',
- '32',
- 'annotations',
- 'annotations-autorange',
- 'axes_labels',
- 'candlestick_double-y-axis',
- 'candlestick_rangeslider_thai',
- 'category-autorange',
- 'contour_match_edges',
- 'dendrogram',
- 'error_bar_style',
- 'fake_violins',
- 'fonts',
- 'font-variant-bar',
- 'font-weight-bar',
- 'geo_africa-insets',
- 'gl2d_10',
- 'gl2d_12',
- 'gl2d_14',
- 'gl2d_17',
- 'gl2d_annotations',
- 'gl2d_axes_labels',
- 'gl2d_fill_trace_tozero_order',
- 'gl2d_fonts',
- 'gl2d_layout_image',
- 'gl2d_marker_coloraxis',
- 'gl2d_rgb_dont_accept_alpha_scattergl',
- 'gl2d_scatter-marker-line-colorscales',
- 'gl2d_scatter-subplot-panel',
- 'gl2d_shape_line',
- 'gl2d_text_chart_basic',
- 'gl2d_text_chart_single-string',
- 'gl2d_text_chart_styling',
- 'gl2d_texttemplate',
- 'gl3d_bunny',
- 'gl3d_bunny-hull',
- 'gl3d_coloraxes',
- 'gl3d_contour-lines',
- 'gl3d_contour-lines2',
- 'gl3d_convex-hull',
- 'gl3d_cufflinks',
- 'gl3d_directions-volume1',
- 'gl3d_ibm-plot',
- 'gl3d_line-colorscale-with-markers',
- 'gl3d_opacity-surface',
- 'gl3d_scatter-colorscale-marker',
- 'gl3d_scatter3d-align-texts',
- 'gl3d_surface_opacity-and-opacityscale',
- 'gl3d_surface_opacityscale_contour',
- 'gl3d_surface-heatmap-treemap_transparent-colorscale',
- 'gl3d_surface-lighting',
- 'gl3d_traces-with-legend',
- 'gl3d_traces-with-opacity',
- 'gl3d_volume_multiple-traces',
- 'gl3d_z-range',
- 'glpolar_scatter',
- 'heatmap_small_aspect-ratio',
- 'histogram_errorbars_inherit_color',
- 'indicator_attrs',
- 'indicator_bignumber',
- 'indicator_bullet',
- 'indicator_datacard',
- 'indicator_datacard2',
- 'indicator_gauge',
- 'indicator_scatter',
- 'japanese',
- 'layout_image',
- 'layout_metatext',
- 'legend_horizontal',
- 'legend_horizontal_autowrap',
- 'legend-constant-itemsizing',
- 'matching-missing-axes',
- 'mathjax',
- 'ohlc_first',
- 'pattern_bars',
- 'pattern_fgcolor_overlay_fillmode',
- 'pattern_with_colorscale',
- 'petrophysics',
- 'plot_types',
- 'polar_blank',
- 'polar_dates',
- 'range_slider_box',
- 'shapes_fixed_size',
- 'splom_ragged-via-axes',
- 'stacked_area_duplicates',
- 'table_plain_birds',
- 'table_wrapped_birds',
- 'text_chart_basic',
- 'text_chart_single-string',
- 'text_chart_styling',
- 'texttemplate',
- 'texttemplate_scatter',
- 'titles-avoid-labels',
- 'trace_metatext',
- 'updatemenus',
- 'violin_non-linear',
- 'violin_ridgeplot',
- 'violin_style',
- 'waterfall_funnel_texttemplate_date',
- 'yaxis-over-yaxis2',
- 'yignbu_heatmap',
- 'yiorrd_heatmap'
- ].indexOf(name) === -1;
+ parentPort.postMessage(failedMocks);
}
diff --git a/test/image/baselines/zz-geo_choropleth-egypt-sudan.png b/test/image/baselines/geo_choropleth-egypt-sudan.png
similarity index 100%
rename from test/image/baselines/zz-geo_choropleth-egypt-sudan.png
rename to test/image/baselines/geo_choropleth-egypt-sudan.png
diff --git a/test/image/baselines/geo_choropleth-usa-location-names.png b/test/image/baselines/geo_choropleth-usa-location-names.png
new file mode 100644
index 00000000000..dc8b76e4608
Binary files /dev/null and b/test/image/baselines/geo_choropleth-usa-location-names.png differ
diff --git a/test/image/baselines/geo_choropleth-usa.png b/test/image/baselines/geo_choropleth-usa.png
index 16716b556bf..427da45e20c 100644
Binary files a/test/image/baselines/geo_choropleth-usa.png and b/test/image/baselines/geo_choropleth-usa.png differ
diff --git a/test/image/baselines/zz-label-spacing.png b/test/image/baselines/label-spacing.png
similarity index 100%
rename from test/image/baselines/zz-label-spacing.png
rename to test/image/baselines/label-spacing.png
diff --git a/test/image/baselines/zz-legend-vertical-maxheight.png b/test/image/baselines/legend-vertical-maxheight.png
similarity index 100%
rename from test/image/baselines/zz-legend-vertical-maxheight.png
rename to test/image/baselines/legend-vertical-maxheight.png
diff --git a/test/image/baselines/zz-minorloglabels.png b/test/image/baselines/minorloglabels.png
similarity index 100%
rename from test/image/baselines/zz-minorloglabels.png
rename to test/image/baselines/minorloglabels.png
diff --git a/test/image/baselines/zz-pattern_bars-path.png b/test/image/baselines/pattern_bars-path.png
similarity index 100%
rename from test/image/baselines/zz-pattern_bars-path.png
rename to test/image/baselines/pattern_bars-path.png
diff --git a/test/image/baselines/zz-pie-slice-legend.png b/test/image/baselines/pie-slice-legend.png
similarity index 100%
rename from test/image/baselines/zz-pie-slice-legend.png
rename to test/image/baselines/pie-slice-legend.png
diff --git a/test/image/baselines/zz-pie-slice-legend2.png b/test/image/baselines/pie-slice-legend2.png
similarity index 100%
rename from test/image/baselines/zz-pie-slice-legend2.png
rename to test/image/baselines/pie-slice-legend2.png
diff --git a/test/image/baselines/zz-pie-slice-legend3.png b/test/image/baselines/pie-slice-legend3.png
similarity index 100%
rename from test/image/baselines/zz-pie-slice-legend3.png
rename to test/image/baselines/pie-slice-legend3.png
diff --git a/test/image/baselines/round-worldcup.png b/test/image/baselines/round-worldcup.png
index 784f8553528..bba92a43609 100644
Binary files a/test/image/baselines/round-worldcup.png and b/test/image/baselines/round-worldcup.png differ
diff --git a/test/image/baselines/zz-scatter_marker_line_dash.png b/test/image/baselines/scatter_marker_line_dash.png
similarity index 100%
rename from test/image/baselines/zz-scatter_marker_line_dash.png
rename to test/image/baselines/scatter_marker_line_dash.png
diff --git a/test/image/baselines/zz_shapes_clipping_double_digit_subplots.png b/test/image/baselines/shapes_clipping_double_digit_subplots.png
similarity index 100%
rename from test/image/baselines/zz_shapes_clipping_double_digit_subplots.png
rename to test/image/baselines/shapes_clipping_double_digit_subplots.png
diff --git a/test/image/baselines/sunburst_coffee.png b/test/image/baselines/sunburst_coffee.png
index 590edb08ba9..523744ad90d 100644
Binary files a/test/image/baselines/sunburst_coffee.png and b/test/image/baselines/sunburst_coffee.png differ
diff --git a/test/image/baselines/sunburst_flare.png b/test/image/baselines/sunburst_flare.png
index 26d55ac5306..922ededcc65 100644
Binary files a/test/image/baselines/sunburst_flare.png and b/test/image/baselines/sunburst_flare.png differ
diff --git a/test/image/baselines/zz-tickson_boundaries_ticklabelposition.png b/test/image/baselines/tickson_boundaries_ticklabelposition.png
similarity index 100%
rename from test/image/baselines/zz-tickson_boundaries_ticklabelposition.png
rename to test/image/baselines/tickson_boundaries_ticklabelposition.png
diff --git a/test/image/baselines/treemap_packages_colorscale_novalue.png b/test/image/baselines/treemap_packages_colorscale_novalue.png
index 0ec48aa585b..5efd24ef2d9 100644
Binary files a/test/image/baselines/treemap_packages_colorscale_novalue.png and b/test/image/baselines/treemap_packages_colorscale_novalue.png differ
diff --git a/test/image/baselines/treemap_sunburst_marker_colors.png b/test/image/baselines/treemap_sunburst_marker_colors.png
index 209427c1b2a..3a45878bbec 100644
Binary files a/test/image/baselines/treemap_sunburst_marker_colors.png and b/test/image/baselines/treemap_sunburst_marker_colors.png differ
diff --git a/test/image/baselines/treemap_textfit.png b/test/image/baselines/treemap_textfit.png
index c5822e62271..7cbd4c40311 100644
Binary files a/test/image/baselines/treemap_textfit.png and b/test/image/baselines/treemap_textfit.png differ
diff --git a/test/image/baselines/uniformtext_sunburst_treemap.png b/test/image/baselines/uniformtext_sunburst_treemap.png
index 31adc8ab71e..d99afe65a59 100644
Binary files a/test/image/baselines/uniformtext_sunburst_treemap.png and b/test/image/baselines/uniformtext_sunburst_treemap.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d-case-insenstive-colors.png b/test/image/baselines/virtual-webgl___gl2d-case-insenstive-colors.png
new file mode 100644
index 00000000000..823c65415d2
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d-case-insenstive-colors.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_10.png b/test/image/baselines/virtual-webgl___gl2d_10.png
new file mode 100644
index 00000000000..db8d866deb7
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_10.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_12.png b/test/image/baselines/virtual-webgl___gl2d_12.png
new file mode 100644
index 00000000000..4b2645cfdac
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_12.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_14.png b/test/image/baselines/virtual-webgl___gl2d_14.png
new file mode 100644
index 00000000000..b6dc076b6bb
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_14.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_17.png b/test/image/baselines/virtual-webgl___gl2d_17.png
new file mode 100644
index 00000000000..d891b89083c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_17.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_annotations.png b/test/image/baselines/virtual-webgl___gl2d_annotations.png
new file mode 100644
index 00000000000..47c8ecd2c4c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_annotations.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_booleans.png b/test/image/baselines/virtual-webgl___gl2d_axes_booleans.png
new file mode 100644
index 00000000000..6cfbfdcc112
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_booleans.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_labels.png b/test/image/baselines/virtual-webgl___gl2d_axes_labels.png
new file mode 100644
index 00000000000..6ddd7e715e4
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_labels.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_labels2.png b/test/image/baselines/virtual-webgl___gl2d_axes_labels2.png
new file mode 100644
index 00000000000..2bf9c2bb20c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_labels2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_lines.png b/test/image/baselines/virtual-webgl___gl2d_axes_lines.png
new file mode 100644
index 00000000000..dcd83dae8f9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_lines.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_range_manual.png b/test/image/baselines/virtual-webgl___gl2d_axes_range_manual.png
new file mode 100644
index 00000000000..1512a960a50
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_range_manual.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_range_mode.png b/test/image/baselines/virtual-webgl___gl2d_axes_range_mode.png
new file mode 100644
index 00000000000..5472575a68f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_range_mode.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_axes_range_type.png b/test/image/baselines/virtual-webgl___gl2d_axes_range_type.png
new file mode 100644
index 00000000000..b10dff16d18
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_axes_range_type.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_clean-number.png b/test/image/baselines/virtual-webgl___gl2d_clean-number.png
new file mode 100644
index 00000000000..65402b08da1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_clean-number.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_clustering.png b/test/image/baselines/virtual-webgl___gl2d_clustering.png
new file mode 100644
index 00000000000..e55dd58e668
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_clustering.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_connect_gaps.png b/test/image/baselines/virtual-webgl___gl2d_connect_gaps.png
new file mode 100644
index 00000000000..b31769826de
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_connect_gaps.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_date_axes.png b/test/image/baselines/virtual-webgl___gl2d_date_axes.png
new file mode 100644
index 00000000000..15c977098a2
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_date_axes.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_error_bars.png b/test/image/baselines/virtual-webgl___gl2d_error_bars.png
new file mode 100644
index 00000000000..930485d7fa1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_error_bars.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_error_bars_log.png b/test/image/baselines/virtual-webgl___gl2d_error_bars_log.png
new file mode 100644
index 00000000000..356410e29f9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_error_bars_log.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_fill-ordering.png b/test/image/baselines/virtual-webgl___gl2d_fill-ordering.png
new file mode 100644
index 00000000000..bf097b63aee
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_fill-ordering.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_fill_trace_tozero_order.png b/test/image/baselines/virtual-webgl___gl2d_fill_trace_tozero_order.png
new file mode 100644
index 00000000000..e6342528a20
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_fill_trace_tozero_order.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_font-variant-scatter.png b/test/image/baselines/virtual-webgl___gl2d_font-variant-scatter.png
new file mode 100644
index 00000000000..422d3e16949
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_font-variant-scatter.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_font-weight-scatter.png b/test/image/baselines/virtual-webgl___gl2d_font-weight-scatter.png
new file mode 100644
index 00000000000..0b43b328509
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_font-weight-scatter.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_fonts.png b/test/image/baselines/virtual-webgl___gl2d_fonts.png
new file mode 100644
index 00000000000..72bc5c89c1e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_fonts.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_horiz-lines.png b/test/image/baselines/virtual-webgl___gl2d_horiz-lines.png
new file mode 100644
index 00000000000..3abb24601da
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_horiz-lines.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_layout_image.png b/test/image/baselines/virtual-webgl___gl2d_layout_image.png
new file mode 100644
index 00000000000..74e4847c193
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_layout_image.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_line_aligned.png b/test/image/baselines/virtual-webgl___gl2d_line_aligned.png
new file mode 100644
index 00000000000..76370cb0241
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_line_aligned.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_line_dash.png b/test/image/baselines/virtual-webgl___gl2d_line_dash.png
new file mode 100644
index 00000000000..82a5be9808d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_line_dash.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_line_limit.png b/test/image/baselines/virtual-webgl___gl2d_line_limit.png
new file mode 100644
index 00000000000..b69a6d47092
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_line_limit.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_line_select.png b/test/image/baselines/virtual-webgl___gl2d_line_select.png
new file mode 100644
index 00000000000..43998eed0a3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_line_select.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_lines_almost_horizontal_vertical.png b/test/image/baselines/virtual-webgl___gl2d_lines_almost_horizontal_vertical.png
new file mode 100644
index 00000000000..d11d5b77898
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_lines_almost_horizontal_vertical.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_marker_coloraxis.png b/test/image/baselines/virtual-webgl___gl2d_marker_coloraxis.png
new file mode 100644
index 00000000000..7ee362e86c5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_marker_coloraxis.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_marker_line_width.png b/test/image/baselines/virtual-webgl___gl2d_marker_line_width.png
new file mode 100644
index 00000000000..7190ef9f369
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_marker_line_width.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_marker_size.png b/test/image/baselines/virtual-webgl___gl2d_marker_size.png
new file mode 100644
index 00000000000..81a8a5a685c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_marker_size.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_marker_symbols-angle.png b/test/image/baselines/virtual-webgl___gl2d_marker_symbols-angle.png
new file mode 100644
index 00000000000..9aabcb4ba21
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_marker_symbols-angle.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_marker_symbols.png b/test/image/baselines/virtual-webgl___gl2d_marker_symbols.png
new file mode 100644
index 00000000000..12befd314dc
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_marker_symbols.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_multiple-traces-axes-labels.png b/test/image/baselines/virtual-webgl___gl2d_multiple-traces-axes-labels.png
new file mode 100644
index 00000000000..e60b388a62c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_multiple-traces-axes-labels.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_multiple-traces-axes.png b/test/image/baselines/virtual-webgl___gl2d_multiple-traces-axes.png
new file mode 100644
index 00000000000..b0cc42a9861
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_multiple-traces-axes.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_multiple_subplots.png b/test/image/baselines/virtual-webgl___gl2d_multiple_subplots.png
new file mode 100644
index 00000000000..7acb299d776
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_multiple_subplots.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_no-clustering.png b/test/image/baselines/virtual-webgl___gl2d_no-clustering.png
new file mode 100644
index 00000000000..ceadf2dd0e5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_no-clustering.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_no-clustering2.png b/test/image/baselines/virtual-webgl___gl2d_no-clustering2.png
new file mode 100644
index 00000000000..abd0ed4831b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_no-clustering2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_open_marker_line_width.png b/test/image/baselines/virtual-webgl___gl2d_open_marker_line_width.png
new file mode 100644
index 00000000000..510ea544c49
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_open_marker_line_width.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_order_error.png b/test/image/baselines/virtual-webgl___gl2d_order_error.png
new file mode 100644
index 00000000000..87ea7b6fa20
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_order_error.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords.png b/test/image/baselines/virtual-webgl___gl2d_parcoords.png
new file mode 100644
index 00000000000..a55b5d5794f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_1.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_1.png
new file mode 100644
index 00000000000..65b4701419c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_1.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_2.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_2.png
new file mode 100644
index 00000000000..850c6541e63
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_256_colors.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_256_colors.png
new file mode 100644
index 00000000000..21f2fd5ade8
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_256_colors.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_60_dims.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_60_dims.png
new file mode 100644
index 00000000000..cddd0a411bb
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_60_dims.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_blocks.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_blocks.png
new file mode 100644
index 00000000000..6913c5e46f3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_blocks.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_coloraxis.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_coloraxis.png
new file mode 100644
index 00000000000..2ed315fd34f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_coloraxis.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_constraints.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_constraints.png
new file mode 100644
index 00000000000..3ac4da74a35
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_constraints.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_dark_background.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_dark_background.png
new file mode 100644
index 00000000000..0894cc27e75
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_dark_background.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_large.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_large.png
new file mode 100644
index 00000000000..bf72bfab960
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_large.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-above-below.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-above-below.png
new file mode 100644
index 00000000000..9ead25a3ac3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-above-below.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-all.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-all.png
new file mode 100644
index 00000000000..d318cd9efed
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-all.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-below.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-below.png
new file mode 100644
index 00000000000..dcb276a7f19
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-below.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-none.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-none.png
new file mode 100644
index 00000000000..ee68339a7f1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_out-of-range_selected-none.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_rgba_colorscale.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_rgba_colorscale.png
new file mode 100644
index 00000000000..784a572655f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_rgba_colorscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_select_first_last_enum.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_select_first_last_enum.png
new file mode 100644
index 00000000000..ff1d640113a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_select_first_last_enum.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_style_labels.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_style_labels.png
new file mode 100644
index 00000000000..74bce01111a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_style_labels.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_parcoords_tick_format.png b/test/image/baselines/virtual-webgl___gl2d_parcoords_tick_format.png
new file mode 100644
index 00000000000..2e47559f51e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_parcoords_tick_format.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_period_positioning.png b/test/image/baselines/virtual-webgl___gl2d_period_positioning.png
new file mode 100644
index 00000000000..e0a64c67507
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_period_positioning.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_point-selection.png b/test/image/baselines/virtual-webgl___gl2d_point-selection.png
new file mode 100644
index 00000000000..31358bef190
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_point-selection.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_rgb_dont_accept_alpha_scattergl.png b/test/image/baselines/virtual-webgl___gl2d_rgb_dont_accept_alpha_scattergl.png
new file mode 100644
index 00000000000..f6b54a9a8fe
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_rgb_dont_accept_alpha_scattergl.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter-color-clustering.png b/test/image/baselines/virtual-webgl___gl2d_scatter-color-clustering.png
new file mode 100644
index 00000000000..4239111825f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter-color-clustering.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter-colorscale-colorbar.png b/test/image/baselines/virtual-webgl___gl2d_scatter-colorscale-colorbar.png
new file mode 100644
index 00000000000..4238ffb016e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter-colorscale-colorbar.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter-colorscale-points.png b/test/image/baselines/virtual-webgl___gl2d_scatter-colorscale-points.png
new file mode 100644
index 00000000000..6bf4b0c33cf
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter-colorscale-points.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter-continuous-clustering.png b/test/image/baselines/virtual-webgl___gl2d_scatter-continuous-clustering.png
new file mode 100644
index 00000000000..2684e6e708d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter-continuous-clustering.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter-marker-line-colorscales.png b/test/image/baselines/virtual-webgl___gl2d_scatter-marker-line-colorscales.png
new file mode 100644
index 00000000000..185b5cfa272
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter-marker-line-colorscales.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter-subplot-panel.png b/test/image/baselines/virtual-webgl___gl2d_scatter-subplot-panel.png
new file mode 100644
index 00000000000..9563423d3be
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter-subplot-panel.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter2d-multiple-colors.png b/test/image/baselines/virtual-webgl___gl2d_scatter2d-multiple-colors.png
new file mode 100644
index 00000000000..e1f14a041f3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter2d-multiple-colors.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter_fill_self_next.png b/test/image/baselines/virtual-webgl___gl2d_scatter_fill_self_next.png
new file mode 100644
index 00000000000..2043323b485
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter_fill_self_next.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scatter_fill_self_next_vs_nogl.png b/test/image/baselines/virtual-webgl___gl2d_scatter_fill_self_next_vs_nogl.png
new file mode 100644
index 00000000000..5c5e402b3d7
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scatter_fill_self_next_vs_nogl.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scattergl_errorbars_inherit_color.png b/test/image/baselines/virtual-webgl___gl2d_scattergl_errorbars_inherit_color.png
new file mode 100644
index 00000000000..26f9b6d87cd
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scattergl_errorbars_inherit_color.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scattergl_gaps.png b/test/image/baselines/virtual-webgl___gl2d_scattergl_gaps.png
new file mode 100644
index 00000000000..9ec20a60887
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scattergl_gaps.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_scattergl_simple_line_reversed_ranges.png b/test/image/baselines/virtual-webgl___gl2d_scattergl_simple_line_reversed_ranges.png
new file mode 100644
index 00000000000..e7b4d65847a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_scattergl_simple_line_reversed_ranges.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_selectedpoints.png b/test/image/baselines/virtual-webgl___gl2d_selectedpoints.png
new file mode 100644
index 00000000000..18f3ec2cde9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_selectedpoints.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_shape_line.png b/test/image/baselines/virtual-webgl___gl2d_shape_line.png
new file mode 100644
index 00000000000..7b53ef2dd8f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_shape_line.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_shapes_below_traces.png b/test/image/baselines/virtual-webgl___gl2d_shapes_below_traces.png
new file mode 100644
index 00000000000..38c95485b09
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_shapes_below_traces.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_simple_inset.png b/test/image/baselines/virtual-webgl___gl2d_simple_inset.png
new file mode 100644
index 00000000000..9c92cefbd47
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_simple_inset.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_size_margins.png b/test/image/baselines/virtual-webgl___gl2d_size_margins.png
new file mode 100644
index 00000000000..3d6d45e9a7e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_size_margins.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_stacked_coupled_subplots.png b/test/image/baselines/virtual-webgl___gl2d_stacked_coupled_subplots.png
new file mode 100644
index 00000000000..edfb094d691
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_stacked_coupled_subplots.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_stacked_subplots.png b/test/image/baselines/virtual-webgl___gl2d_stacked_subplots.png
new file mode 100644
index 00000000000..36d32c130a6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_stacked_subplots.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_subplots_anchor.png b/test/image/baselines/virtual-webgl___gl2d_subplots_anchor.png
new file mode 100644
index 00000000000..1456cbf9ed5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_subplots_anchor.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_symbol_numbers.png b/test/image/baselines/virtual-webgl___gl2d_symbol_numbers.png
new file mode 100644
index 00000000000..67c31206969
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_symbol_numbers.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_text_chart_arrays.png b/test/image/baselines/virtual-webgl___gl2d_text_chart_arrays.png
new file mode 100644
index 00000000000..6b02c0e139a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_text_chart_arrays.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_text_chart_basic.png b/test/image/baselines/virtual-webgl___gl2d_text_chart_basic.png
new file mode 100644
index 00000000000..1ae27c37161
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_text_chart_basic.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_text_chart_invalid-arrays.png b/test/image/baselines/virtual-webgl___gl2d_text_chart_invalid-arrays.png
new file mode 100644
index 00000000000..dd9561fe9d9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_text_chart_invalid-arrays.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_text_chart_single-string.png b/test/image/baselines/virtual-webgl___gl2d_text_chart_single-string.png
new file mode 100644
index 00000000000..fa49acad971
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_text_chart_single-string.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_text_chart_styling.png b/test/image/baselines/virtual-webgl___gl2d_text_chart_styling.png
new file mode 100644
index 00000000000..73f268fcb55
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_text_chart_styling.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_texttemplate.png b/test/image/baselines/virtual-webgl___gl2d_texttemplate.png
new file mode 100644
index 00000000000..7fc90d9aa0b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_texttemplate.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_tick-labels.png b/test/image/baselines/virtual-webgl___gl2d_tick-labels.png
new file mode 100644
index 00000000000..ee4d664478e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_tick-labels.png differ
diff --git a/test/image/baselines/virtual-webgl___gl2d_ultra_zoom.png b/test/image/baselines/virtual-webgl___gl2d_ultra_zoom.png
new file mode 100644
index 00000000000..fd96e28e3a4
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl2d_ultra_zoom.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_alphahull5.png b/test/image/baselines/virtual-webgl___gl3d_alphahull5.png
new file mode 100644
index 00000000000..e02dd5e9f7f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_alphahull5.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_annotations.png b/test/image/baselines/virtual-webgl___gl3d_annotations.png
new file mode 100644
index 00000000000..b133b822b46
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_annotations.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_annotations_orthographic.png b/test/image/baselines/virtual-webgl___gl3d_annotations_orthographic.png
new file mode 100644
index 00000000000..913511a07ba
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_annotations_orthographic.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_autocolorscale.png b/test/image/baselines/virtual-webgl___gl3d_autocolorscale.png
new file mode 100644
index 00000000000..743f5d2d1ae
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_autocolorscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_autorange-zero.png b/test/image/baselines/virtual-webgl___gl3d_autorange-zero.png
new file mode 100644
index 00000000000..8cef46d9950
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_autorange-zero.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_axes-visible-false.png b/test/image/baselines/virtual-webgl___gl3d_axes-visible-false.png
new file mode 100644
index 00000000000..8226dc8cda1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_axes-visible-false.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_bunny-hull.png b/test/image/baselines/virtual-webgl___gl3d_bunny-hull.png
new file mode 100644
index 00000000000..e44d1867c0e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_bunny-hull.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_bunny.png b/test/image/baselines/virtual-webgl___gl3d_bunny.png
new file mode 100644
index 00000000000..45868f391a9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_bunny.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_bunny_cell-area.png b/test/image/baselines/virtual-webgl___gl3d_bunny_cell-area.png
new file mode 100644
index 00000000000..49391b54432
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_bunny_cell-area.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_chrisp-nan-1.png b/test/image/baselines/virtual-webgl___gl3d_chrisp-nan-1.png
new file mode 100644
index 00000000000..5cfe4cd77ec
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_chrisp-nan-1.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_coloraxes.png b/test/image/baselines/virtual-webgl___gl3d_coloraxes.png
new file mode 100644
index 00000000000..7dd80f57352
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_coloraxes.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_colormap256.png b/test/image/baselines/virtual-webgl___gl3d_colormap256.png
new file mode 100644
index 00000000000..edaf43fbed2
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_colormap256.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-absolute.png b/test/image/baselines/virtual-webgl___gl3d_cone-absolute.png
new file mode 100644
index 00000000000..cecdda80533
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-absolute.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-autorange.png b/test/image/baselines/virtual-webgl___gl3d_cone-autorange.png
new file mode 100644
index 00000000000..c8606581185
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-autorange.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-lighting.png b/test/image/baselines/virtual-webgl___gl3d_cone-lighting.png
new file mode 100644
index 00000000000..4c46973e37e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-lighting.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-newplot_reversed_ranges.png b/test/image/baselines/virtual-webgl___gl3d_cone-newplot_reversed_ranges.png
new file mode 100644
index 00000000000..a67c9339252
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-newplot_reversed_ranges.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-rossler.png b/test/image/baselines/virtual-webgl___gl3d_cone-rossler.png
new file mode 100644
index 00000000000..c768f639cf4
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-rossler.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-simple.png b/test/image/baselines/virtual-webgl___gl3d_cone-simple.png
new file mode 100644
index 00000000000..2eda2854fa7
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-simple.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-single.png b/test/image/baselines/virtual-webgl___gl3d_cone-single.png
new file mode 100644
index 00000000000..0a78fa5e1b6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-single.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-sizemode.png b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode.png
new file mode 100644
index 00000000000..0873f2d27bc
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector.png b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector.png
new file mode 100644
index 00000000000..808838691a5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector2.png b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector2.png
new file mode 100644
index 00000000000..93c0d720385
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector3.png b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector3.png
new file mode 100644
index 00000000000..0819f646b66
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-sizemode_vector3.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-wind.png b/test/image/baselines/virtual-webgl___gl3d_cone-wind.png
new file mode 100644
index 00000000000..2a0a9bb05f6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-wind.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cone-with-streamtube.png b/test/image/baselines/virtual-webgl___gl3d_cone-with-streamtube.png
new file mode 100644
index 00000000000..21beee912d6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cone-with-streamtube.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_contour-lines.png b/test/image/baselines/virtual-webgl___gl3d_contour-lines.png
new file mode 100644
index 00000000000..d476e7cf762
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_contour-lines.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_contour-lines2.png b/test/image/baselines/virtual-webgl___gl3d_contour-lines2.png
new file mode 100644
index 00000000000..008e712e446
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_contour-lines2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_convex-hull.png b/test/image/baselines/virtual-webgl___gl3d_convex-hull.png
new file mode 100644
index 00000000000..45868f391a9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_convex-hull.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cube.png b/test/image/baselines/virtual-webgl___gl3d_cube.png
new file mode 100644
index 00000000000..77c6e7f1e0f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cube.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_cufflinks.png b/test/image/baselines/virtual-webgl___gl3d_cufflinks.png
new file mode 100644
index 00000000000..a574a2b5521
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_cufflinks.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_delaunay.png b/test/image/baselines/virtual-webgl___gl3d_delaunay.png
new file mode 100644
index 00000000000..03156e355b9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_delaunay.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_directions-isosurface1.png b/test/image/baselines/virtual-webgl___gl3d_directions-isosurface1.png
new file mode 100644
index 00000000000..6253bb2b97b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_directions-isosurface1.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_directions-isosurface2.png b/test/image/baselines/virtual-webgl___gl3d_directions-isosurface2.png
new file mode 100644
index 00000000000..1e94ecc9f98
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_directions-isosurface2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_directions-streamtube1.png b/test/image/baselines/virtual-webgl___gl3d_directions-streamtube1.png
new file mode 100644
index 00000000000..d56f95fce1d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_directions-streamtube1.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_directions-streamtube2.png b/test/image/baselines/virtual-webgl___gl3d_directions-streamtube2.png
new file mode 100644
index 00000000000..df4501b8ee4
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_directions-streamtube2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_directions-volume1.png b/test/image/baselines/virtual-webgl___gl3d_directions-volume1.png
new file mode 100644
index 00000000000..8baaf0fa4aa
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_directions-volume1.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_error_bars_log.png b/test/image/baselines/virtual-webgl___gl3d_error_bars_log.png
new file mode 100644
index 00000000000..a9c256c6a94
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_error_bars_log.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_error_bars_log_2.png b/test/image/baselines/virtual-webgl___gl3d_error_bars_log_2.png
new file mode 100644
index 00000000000..1ed5f3fe206
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_error_bars_log_2.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_errorbars_sqrt.png b/test/image/baselines/virtual-webgl___gl3d_errorbars_sqrt.png
new file mode 100644
index 00000000000..55fe6a57e00
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_errorbars_sqrt.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_errorbars_xy.png b/test/image/baselines/virtual-webgl___gl3d_errorbars_xy.png
new file mode 100644
index 00000000000..3575f054cd0
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_errorbars_xy.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_errorbars_zx.png b/test/image/baselines/virtual-webgl___gl3d_errorbars_zx.png
new file mode 100644
index 00000000000..bca549ddd68
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_errorbars_zx.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_errorbars_zy.png b/test/image/baselines/virtual-webgl___gl3d_errorbars_zy.png
new file mode 100644
index 00000000000..c4d6a934eea
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_errorbars_zy.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_font-variant-scatter.png b/test/image/baselines/virtual-webgl___gl3d_font-variant-scatter.png
new file mode 100644
index 00000000000..78b18adf26b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_font-variant-scatter.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_font-weight-scatter.png b/test/image/baselines/virtual-webgl___gl3d_font-weight-scatter.png
new file mode 100644
index 00000000000..178306a6d55
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_font-weight-scatter.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_formatted-text-on-multiple-lines.png b/test/image/baselines/virtual-webgl___gl3d_formatted-text-on-multiple-lines.png
new file mode 100644
index 00000000000..f8bc8cf5373
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_formatted-text-on-multiple-lines.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_ibm-plot.png b/test/image/baselines/virtual-webgl___gl3d_ibm-plot.png
new file mode 100644
index 00000000000..437be8663b0
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_ibm-plot.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_indicator_scatter3d.png b/test/image/baselines/virtual-webgl___gl3d_indicator_scatter3d.png
new file mode 100644
index 00000000000..6e1697a6774
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_indicator_scatter3d.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_1single-surface_middle-range.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_1single-surface_middle-range.png
new file mode 100644
index 00000000000..0bad80de8ff
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_1single-surface_middle-range.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_2surfaces-checker_spaceframe.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_2surfaces-checker_spaceframe.png
new file mode 100644
index 00000000000..d07995785b1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_2surfaces-checker_spaceframe.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_5more-surfaces_between-ranges.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_5more-surfaces_between-ranges.png
new file mode 100644
index 00000000000..27853286602
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_5more-surfaces_between-ranges.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_9more-surfaces_between-ranges_orthographic.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_9more-surfaces_between-ranges_orthographic.png
new file mode 100644
index 00000000000..9e85d5c45bf
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_9more-surfaces_between-ranges_orthographic.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_log-axis_slices_surface-fill.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_log-axis_slices_surface-fill.png
new file mode 100644
index 00000000000..ca82f444a1a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_log-axis_slices_surface-fill.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_math.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_math.png
new file mode 100644
index 00000000000..9faec979b99
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_math.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_multiple-traces.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_multiple-traces.png
new file mode 100644
index 00000000000..1134a51dc89
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_multiple-traces.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_out_of_iso_range_case.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_out_of_iso_range_case.png
new file mode 100644
index 00000000000..39482eabd97
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_out_of_iso_range_case.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_thin_caps_different_dims.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_thin_caps_different_dims.png
new file mode 100644
index 00000000000..f314c1961d7
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_thin_caps_different_dims.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_thin_slices_transparent.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_thin_slices_transparent.png
new file mode 100644
index 00000000000..61a751c728d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_thin_slices_transparent.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_transparent.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_transparent.png
new file mode 100644
index 00000000000..fba9f907054
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_transparent.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_uneven-scales_ranges_iso-null.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_uneven-scales_ranges_iso-null.png
new file mode 100644
index 00000000000..d613a7d7321
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_uneven-scales_ranges_iso-null.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_with_surface-pattern.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_with_surface-pattern.png
new file mode 100644
index 00000000000..78f476582bc
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_with_surface-pattern.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_isosurface_xycaps_volume_slices.png b/test/image/baselines/virtual-webgl___gl3d_isosurface_xycaps_volume_slices.png
new file mode 100644
index 00000000000..7c467cc29e6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_isosurface_xycaps_volume_slices.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_line-colorscale-with-markers.png b/test/image/baselines/virtual-webgl___gl3d_line-colorscale-with-markers.png
new file mode 100644
index 00000000000..33f709d6ff9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_line-colorscale-with-markers.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_line_rectangle_render.png b/test/image/baselines/virtual-webgl___gl3d_line_rectangle_render.png
new file mode 100644
index 00000000000..66fafd4a1e0
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_line_rectangle_render.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_log-axis-big.png b/test/image/baselines/virtual-webgl___gl3d_log-axis-big.png
new file mode 100644
index 00000000000..b2acefada38
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_log-axis-big.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_log-axis.png b/test/image/baselines/virtual-webgl___gl3d_log-axis.png
new file mode 100644
index 00000000000..572f7714fba
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_log-axis.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_marker-arrays.png b/test/image/baselines/virtual-webgl___gl3d_marker-arrays.png
new file mode 100644
index 00000000000..db19f29d46b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_marker-arrays.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_marker-color.png b/test/image/baselines/virtual-webgl___gl3d_marker-color.png
new file mode 100644
index 00000000000..ab14314c2b7
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_marker-color.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_marker_symbols.png b/test/image/baselines/virtual-webgl___gl3d_marker_symbols.png
new file mode 100644
index 00000000000..0f188a28d81
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_marker_symbols.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d-missing-colors.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d-missing-colors.png
new file mode 100644
index 00000000000..ee31ca9683b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d-missing-colors.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d_cell-intensity.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d_cell-intensity.png
new file mode 100644
index 00000000000..f5d6d12b53f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d_cell-intensity.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d_coloring.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d_coloring.png
new file mode 100644
index 00000000000..f67205fa74e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d_coloring.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d_enable-alpha-with-rgba-color.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d_enable-alpha-with-rgba-color.png
new file mode 100644
index 00000000000..c2559f7c0fe
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d_enable-alpha-with-rgba-color.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface3d_scatter3d_line3d_error3d_log_reversed_ranges.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface3d_scatter3d_line3d_error3d_log_reversed_ranges.png
new file mode 100644
index 00000000000..62196124dbe
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface3d_scatter3d_line3d_error3d_log_reversed_ranges.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface3d_scatter3d_orthographic.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface3d_scatter3d_orthographic.png
new file mode 100644
index 00000000000..f1f165b0141
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface3d_scatter3d_orthographic.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface_lighting.png b/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface_lighting.png
new file mode 100644
index 00000000000..458376ef23b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mesh3d_surface_lighting.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_mirror-ticks.png b/test/image/baselines/virtual-webgl___gl3d_mirror-ticks.png
new file mode 100644
index 00000000000..b71f6cbae7e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_mirror-ticks.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_multi-scene.png b/test/image/baselines/virtual-webgl___gl3d_multi-scene.png
new file mode 100644
index 00000000000..61fd5fea123
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_multi-scene.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_multiple-scatter3d-traces.png b/test/image/baselines/virtual-webgl___gl3d_multiple-scatter3d-traces.png
new file mode 100644
index 00000000000..6b8d2992a1d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_multiple-scatter3d-traces.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_nan-holes.png b/test/image/baselines/virtual-webgl___gl3d_nan-holes.png
new file mode 100644
index 00000000000..3305c517eb9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_nan-holes.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_opacity-scaling-spikes.png b/test/image/baselines/virtual-webgl___gl3d_opacity-scaling-spikes.png
new file mode 100644
index 00000000000..5e4eaa0d1c8
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_opacity-scaling-spikes.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_opacity-surface.png b/test/image/baselines/virtual-webgl___gl3d_opacity-surface.png
new file mode 100644
index 00000000000..9830960a9e2
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_opacity-surface.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_parametric_surface_data_precision.png b/test/image/baselines/virtual-webgl___gl3d_parametric_surface_data_precision.png
new file mode 100644
index 00000000000..fa23a89c135
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_parametric_surface_data_precision.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_perspective_tick_distances.png b/test/image/baselines/virtual-webgl___gl3d_perspective_tick_distances.png
new file mode 100644
index 00000000000..4368733c824
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_perspective_tick_distances.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_projection-traces.png b/test/image/baselines/virtual-webgl___gl3d_projection-traces.png
new file mode 100644
index 00000000000..b942a0855d1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_projection-traces.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_reversescale.png b/test/image/baselines/virtual-webgl___gl3d_reversescale.png
new file mode 100644
index 00000000000..232adb8770f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_reversescale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_rgb_dont_accept_alpha_scatter3d.png b/test/image/baselines/virtual-webgl___gl3d_rgb_dont_accept_alpha_scatter3d.png
new file mode 100644
index 00000000000..1d988c9902c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_rgb_dont_accept_alpha_scatter3d.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_ribbons.png b/test/image/baselines/virtual-webgl___gl3d_ribbons.png
new file mode 100644
index 00000000000..2254578b2a3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_ribbons.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter-color-array.png b/test/image/baselines/virtual-webgl___gl3d_scatter-color-array.png
new file mode 100644
index 00000000000..d3401240388
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter-color-array.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter-color-line-gradient.png b/test/image/baselines/virtual-webgl___gl3d_scatter-color-line-gradient.png
new file mode 100644
index 00000000000..19749116d48
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter-color-line-gradient.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter-color-mono-and-palette.png b/test/image/baselines/virtual-webgl___gl3d_scatter-color-mono-and-palette.png
new file mode 100644
index 00000000000..6a3d21e8fe5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter-color-mono-and-palette.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter-colorscale-marker.png b/test/image/baselines/virtual-webgl___gl3d_scatter-colorscale-marker.png
new file mode 100644
index 00000000000..20dd82a54b0
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter-colorscale-marker.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-align-texts.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-align-texts.png
new file mode 100644
index 00000000000..f5aa70b00e7
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-align-texts.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-blank-text.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-blank-text.png
new file mode 100644
index 00000000000..13b3e78af87
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-blank-text.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale-marker-and-line.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale-marker-and-line.png
new file mode 100644
index 00000000000..e59f36e3952
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale-marker-and-line.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale-with-line.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale-with-line.png
new file mode 100644
index 00000000000..e8cf7bb90e9
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale-with-line.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale.png
new file mode 100644
index 00000000000..3012767077d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-colorscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-connectgaps.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-connectgaps.png
new file mode 100644
index 00000000000..7d5c1723feb
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-connectgaps.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-different-align-texts.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-different-align-texts.png
new file mode 100644
index 00000000000..d1ccd06405e
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-different-align-texts.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d-texttemplate.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d-texttemplate.png
new file mode 100644
index 00000000000..0a0994dcdfb
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d-texttemplate.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d_errorbars_inherit_color.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d_errorbars_inherit_color.png
new file mode 100644
index 00000000000..c7da0b11bce
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d_errorbars_inherit_color.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d_line3d_error3d_enable-alpha-with-rgba-color.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d_line3d_error3d_enable-alpha-with-rgba-color.png
new file mode 100644
index 00000000000..92e8ec21ec5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d_line3d_error3d_enable-alpha-with-rgba-color.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_scatter3d_line3d_error3d_transparent-with-zero-alpha.png b/test/image/baselines/virtual-webgl___gl3d_scatter3d_line3d_error3d_transparent-with-zero-alpha.png
new file mode 100644
index 00000000000..321ca1c3773
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_scatter3d_line3d_error3d_transparent-with-zero-alpha.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_set-ranges.png b/test/image/baselines/virtual-webgl___gl3d_set-ranges.png
new file mode 100644
index 00000000000..e190ce2b855
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_set-ranges.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_snowden.png b/test/image/baselines/virtual-webgl___gl3d_snowden.png
new file mode 100644
index 00000000000..b79bc27a1d5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_snowden.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_snowden_altered.png b/test/image/baselines/virtual-webgl___gl3d_snowden_altered.png
new file mode 100644
index 00000000000..f280cb9027f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_snowden_altered.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_streamtube-first.png b/test/image/baselines/virtual-webgl___gl3d_streamtube-first.png
new file mode 100644
index 00000000000..ad2ea12e655
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_streamtube-first.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_streamtube-simple.png b/test/image/baselines/virtual-webgl___gl3d_streamtube-simple.png
new file mode 100644
index 00000000000..795f39bff61
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_streamtube-simple.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_streamtube-thin.png b/test/image/baselines/virtual-webgl___gl3d_streamtube-thin.png
new file mode 100644
index 00000000000..370a705ce20
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_streamtube-thin.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_streamtube-wind.png b/test/image/baselines/virtual-webgl___gl3d_streamtube-wind.png
new file mode 100644
index 00000000000..ee1619330f3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_streamtube-wind.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_streamtube_reversed_ranges.png b/test/image/baselines/virtual-webgl___gl3d_streamtube_reversed_ranges.png
new file mode 100644
index 00000000000..ea02a3afb5a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_streamtube_reversed_ranges.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface-circular-colorscale.png b/test/image/baselines/virtual-webgl___gl3d_surface-circular-colorscale.png
new file mode 100644
index 00000000000..34c9d7f3051
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface-circular-colorscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface-circular-opacityscale.png b/test/image/baselines/virtual-webgl___gl3d_surface-circular-opacityscale.png
new file mode 100644
index 00000000000..a5bd03924e6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface-circular-opacityscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface-heatmap-treemap_transparent-colorscale.png b/test/image/baselines/virtual-webgl___gl3d_surface-heatmap-treemap_transparent-colorscale.png
new file mode 100644
index 00000000000..16bc09dcc5f
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface-heatmap-treemap_transparent-colorscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface-lighting.png b/test/image/baselines/virtual-webgl___gl3d_surface-lighting.png
new file mode 100644
index 00000000000..d5c49c99e2b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface-lighting.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_after_heatmap.png b/test/image/baselines/virtual-webgl___gl3d_surface_after_heatmap.png
new file mode 100644
index 00000000000..5a4b2390f49
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_after_heatmap.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_connectgaps.png b/test/image/baselines/virtual-webgl___gl3d_surface_connectgaps.png
new file mode 100644
index 00000000000..0734b559114
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_connectgaps.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_contour_precision.png b/test/image/baselines/virtual-webgl___gl3d_surface_contour_precision.png
new file mode 100644
index 00000000000..31a477569e3
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_contour_precision.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_contour_start-end-size.png b/test/image/baselines/virtual-webgl___gl3d_surface_contour_start-end-size.png
new file mode 100644
index 00000000000..e67a28cb476
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_contour_start-end-size.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_intensity.png b/test/image/baselines/virtual-webgl___gl3d_surface_intensity.png
new file mode 100644
index 00000000000..819a8863e5c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_intensity.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_opacity-and-opacityscale.png b/test/image/baselines/virtual-webgl___gl3d_surface_opacity-and-opacityscale.png
new file mode 100644
index 00000000000..ee26034ba66
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_opacity-and-opacityscale.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_opacity_match_mesh3d.png b/test/image/baselines/virtual-webgl___gl3d_surface_opacity_match_mesh3d.png
new file mode 100644
index 00000000000..42cc26f8517
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_opacity_match_mesh3d.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_opacityscale_contour.png b/test/image/baselines/virtual-webgl___gl3d_surface_opacityscale_contour.png
new file mode 100644
index 00000000000..4a5e887e587
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_opacityscale_contour.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_small_timerange.png b/test/image/baselines/virtual-webgl___gl3d_surface_small_timerange.png
new file mode 100644
index 00000000000..f7fc8a6e60d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_small_timerange.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_surface_transparent-with-contours.png b/test/image/baselines/virtual-webgl___gl3d_surface_transparent-with-contours.png
new file mode 100644
index 00000000000..30336e0b213
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_surface_transparent-with-contours.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_tetrahedra.png b/test/image/baselines/virtual-webgl___gl3d_tetrahedra.png
new file mode 100644
index 00000000000..ff9f83168af
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_tetrahedra.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_text-weirdness.png b/test/image/baselines/virtual-webgl___gl3d_text-weirdness.png
new file mode 100644
index 00000000000..1a931922c65
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_text-weirdness.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_ticks-milliseconds.png b/test/image/baselines/virtual-webgl___gl3d_ticks-milliseconds.png
new file mode 100644
index 00000000000..239ba0de67c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_ticks-milliseconds.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_traces-with-legend.png b/test/image/baselines/virtual-webgl___gl3d_traces-with-legend.png
new file mode 100644
index 00000000000..32f3a990d7d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_traces-with-legend.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_traces-with-opacity.png b/test/image/baselines/virtual-webgl___gl3d_traces-with-opacity.png
new file mode 100644
index 00000000000..522725c0e96
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_traces-with-opacity.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_transparent_same-depth.png b/test/image/baselines/virtual-webgl___gl3d_transparent_same-depth.png
new file mode 100644
index 00000000000..523c0ebb92c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_transparent_same-depth.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_triangle.png b/test/image/baselines/virtual-webgl___gl3d_triangle.png
new file mode 100644
index 00000000000..53ae501181b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_triangle.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_volume_airflow.png b/test/image/baselines/virtual-webgl___gl3d_volume_airflow.png
new file mode 100644
index 00000000000..30315739e8b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_volume_airflow.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_volume_multiple-traces.png b/test/image/baselines/virtual-webgl___gl3d_volume_multiple-traces.png
new file mode 100644
index 00000000000..12b0016f88b
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_volume_multiple-traces.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_volume_multiple-traces_one-cube.png b/test/image/baselines/virtual-webgl___gl3d_volume_multiple-traces_one-cube.png
new file mode 100644
index 00000000000..9a8b83e68cb
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_volume_multiple-traces_one-cube.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_volume_opacityscale-iso.png b/test/image/baselines/virtual-webgl___gl3d_volume_opacityscale-iso.png
new file mode 100644
index 00000000000..e34a8f78e64
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_volume_opacityscale-iso.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_wire-surface.png b/test/image/baselines/virtual-webgl___gl3d_wire-surface.png
new file mode 100644
index 00000000000..1c1e3d23e7c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_wire-surface.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_world-cals.png b/test/image/baselines/virtual-webgl___gl3d_world-cals.png
new file mode 100644
index 00000000000..e92bace3373
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_world-cals.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_xy-defined-ticks.png b/test/image/baselines/virtual-webgl___gl3d_xy-defined-ticks.png
new file mode 100644
index 00000000000..9b6e95023a5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_xy-defined-ticks.png differ
diff --git a/test/image/baselines/virtual-webgl___gl3d_z-range.png b/test/image/baselines/virtual-webgl___gl3d_z-range.png
new file mode 100644
index 00000000000..be05d221819
Binary files /dev/null and b/test/image/baselines/virtual-webgl___gl3d_z-range.png differ
diff --git a/test/image/baselines/virtual-webgl___global_font.png b/test/image/baselines/virtual-webgl___global_font.png
new file mode 100644
index 00000000000..9c98ade7a14
Binary files /dev/null and b/test/image/baselines/virtual-webgl___global_font.png differ
diff --git a/test/image/baselines/virtual-webgl___glpolar_scatter.png b/test/image/baselines/virtual-webgl___glpolar_scatter.png
new file mode 100644
index 00000000000..90f203bb360
Binary files /dev/null and b/test/image/baselines/virtual-webgl___glpolar_scatter.png differ
diff --git a/test/image/baselines/virtual-webgl___glpolar_style.png b/test/image/baselines/virtual-webgl___glpolar_style.png
new file mode 100644
index 00000000000..6c5c9df477c
Binary files /dev/null and b/test/image/baselines/virtual-webgl___glpolar_style.png differ
diff --git a/test/image/baselines/virtual-webgl___glpolar_subplots.png b/test/image/baselines/virtual-webgl___glpolar_subplots.png
new file mode 100644
index 00000000000..e02b8bfb748
Binary files /dev/null and b/test/image/baselines/virtual-webgl___glpolar_subplots.png differ
diff --git a/test/image/baselines/virtual-webgl___map_0.png b/test/image/baselines/virtual-webgl___map_0.png
new file mode 100644
index 00000000000..d7d5618c8fb
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_0.png differ
diff --git a/test/image/baselines/virtual-webgl___map_bubbles-text.png b/test/image/baselines/virtual-webgl___map_bubbles-text.png
new file mode 100644
index 00000000000..ce7a38cc794
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_bubbles-text.png differ
diff --git a/test/image/baselines/virtual-webgl___map_bubbles.png b/test/image/baselines/virtual-webgl___map_bubbles.png
new file mode 100644
index 00000000000..811241f7ad1
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_bubbles.png differ
diff --git a/test/image/baselines/virtual-webgl___map_carto-style.png b/test/image/baselines/virtual-webgl___map_carto-style.png
new file mode 100644
index 00000000000..e0257bf482d
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_carto-style.png differ
diff --git a/test/image/baselines/virtual-webgl___map_carto-text.png b/test/image/baselines/virtual-webgl___map_carto-text.png
new file mode 100644
index 00000000000..9d234b9433a
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_carto-text.png differ
diff --git a/test/image/baselines/virtual-webgl___map_choropleth-multiple.png b/test/image/baselines/virtual-webgl___map_choropleth-multiple.png
new file mode 100644
index 00000000000..5aa665317d8
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_choropleth-multiple.png differ
diff --git a/test/image/baselines/virtual-webgl___map_choropleth-raw-geojson.png b/test/image/baselines/virtual-webgl___map_choropleth-raw-geojson.png
new file mode 100644
index 00000000000..5d390f47756
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_choropleth-raw-geojson.png differ
diff --git a/test/image/baselines/virtual-webgl___map_choropleth0-legend.png b/test/image/baselines/virtual-webgl___map_choropleth0-legend.png
new file mode 100644
index 00000000000..a8467c4f741
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_choropleth0-legend.png differ
diff --git a/test/image/baselines/virtual-webgl___map_choropleth0.png b/test/image/baselines/virtual-webgl___map_choropleth0.png
new file mode 100644
index 00000000000..1301d5ea9fd
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_choropleth0.png differ
diff --git a/test/image/baselines/virtual-webgl___map_connectgaps.png b/test/image/baselines/virtual-webgl___map_connectgaps.png
new file mode 100644
index 00000000000..6cdcf06d617
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_connectgaps.png differ
diff --git a/test/image/baselines/virtual-webgl___map_custom-style.png b/test/image/baselines/virtual-webgl___map_custom-style.png
new file mode 100644
index 00000000000..6db20064a00
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_custom-style.png differ
diff --git a/test/image/baselines/virtual-webgl___map_density-multiple.png b/test/image/baselines/virtual-webgl___map_density-multiple.png
new file mode 100644
index 00000000000..dd86a2e1986
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_density-multiple.png differ
diff --git a/test/image/baselines/virtual-webgl___map_density-multiple_legend.png b/test/image/baselines/virtual-webgl___map_density-multiple_legend.png
new file mode 100644
index 00000000000..028107681ba
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_density-multiple_legend.png differ
diff --git a/test/image/baselines/virtual-webgl___map_density0-legend.png b/test/image/baselines/virtual-webgl___map_density0-legend.png
new file mode 100644
index 00000000000..f290c2353c5
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_density0-legend.png differ
diff --git a/test/image/baselines/virtual-webgl___map_density0.png b/test/image/baselines/virtual-webgl___map_density0.png
new file mode 100644
index 00000000000..038a2395ae6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_density0.png differ
diff --git a/test/image/baselines/virtual-webgl___map_earthquake-density.png b/test/image/baselines/virtual-webgl___map_earthquake-density.png
new file mode 100644
index 00000000000..8df3af12987
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_earthquake-density.png differ
diff --git a/test/image/baselines/virtual-webgl___map_fill.png b/test/image/baselines/virtual-webgl___map_fill.png
new file mode 100644
index 00000000000..f5447772458
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_fill.png differ
diff --git a/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis-italic.png b/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis-italic.png
new file mode 100644
index 00000000000..2b51bfc6cdd
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis-italic.png differ
diff --git a/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis-weight.png b/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis-weight.png
new file mode 100644
index 00000000000..a239b749370
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis-weight.png differ
diff --git a/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis.png b/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis.png
new file mode 100644
index 00000000000..a239b749370
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_fonts-supported-metropolis.png differ
diff --git a/test/image/baselines/virtual-webgl___map_geojson-attributes.png b/test/image/baselines/virtual-webgl___map_geojson-attributes.png
new file mode 100644
index 00000000000..2a5a70fefba
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_geojson-attributes.png differ
diff --git a/test/image/baselines/virtual-webgl___map_osm-style.png b/test/image/baselines/virtual-webgl___map_osm-style.png
new file mode 100644
index 00000000000..37630b0bdd6
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_osm-style.png differ
diff --git a/test/image/baselines/virtual-webgl___map_predefined-styles1.png b/test/image/baselines/virtual-webgl___map_predefined-styles1.png
new file mode 100644
index 00000000000..be0eecce897
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_predefined-styles1.png differ
diff --git a/test/image/baselines/virtual-webgl___map_symbol-text.png b/test/image/baselines/virtual-webgl___map_symbol-text.png
new file mode 100644
index 00000000000..5b3a919b251
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_symbol-text.png differ
diff --git a/test/image/baselines/virtual-webgl___map_texttemplate.png b/test/image/baselines/virtual-webgl___map_texttemplate.png
new file mode 100644
index 00000000000..245acd67c13
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_texttemplate.png differ
diff --git a/test/image/baselines/virtual-webgl___map_white-bg-style.png b/test/image/baselines/virtual-webgl___map_white-bg-style.png
new file mode 100644
index 00000000000..7b9a35a6b46
Binary files /dev/null and b/test/image/baselines/virtual-webgl___map_white-bg-style.png differ
diff --git a/test/image/baselines/worldcup.png b/test/image/baselines/worldcup.png
index 043d310453b..bbf074b8017 100644
Binary files a/test/image/baselines/worldcup.png and b/test/image/baselines/worldcup.png differ
diff --git a/test/image/baselines/zzz_zerolinelayer_above.png b/test/image/baselines/zerolinelayer_above.png
similarity index 100%
rename from test/image/baselines/zzz_zerolinelayer_above.png
rename to test/image/baselines/zerolinelayer_above.png
diff --git a/test/image/baselines/zzz_zerolinelayer_below.png b/test/image/baselines/zerolinelayer_below.png
similarity index 100%
rename from test/image/baselines/zzz_zerolinelayer_below.png
rename to test/image/baselines/zerolinelayer_below.png
diff --git a/test/image/compare_pixels_collections.json b/test/image/compare_pixels_collections.json
new file mode 100644
index 00000000000..234eb781609
--- /dev/null
+++ b/test/image/compare_pixels_collections.json
@@ -0,0 +1,21 @@
+{
+ "compare_disallow": [
+ "map_angles",
+ "map_fonts-supported-open-sans-weight",
+ "map_fonts-supported-open-sans",
+ "map_layers",
+ "map_predefined-styles2",
+ "map_scattercluster",
+ "map_stamen-style"
+ ],
+ "compare_mathjax3": [
+ "legend_mathjax_title_and_items",
+ "mathjax",
+ "parcats_grid_subplots",
+ "table_latex_multitrace_scatter",
+ "table_plain_birds",
+ "table_wrapped_birds",
+ "ternary-mathjax",
+ "ternary-mathjax-title-place-subtitle"
+ ]
+}
diff --git a/test/image/compare_pixels_test.js b/test/image/compare_pixels_test.js
deleted file mode 100644
index 574e5edf51f..00000000000
--- a/test/image/compare_pixels_test.js
+++ /dev/null
@@ -1,204 +0,0 @@
-var minimist = require('minimist');
-var pixelmatch = require('pixelmatch');
-var PNG = require('pngjs').PNG;
-var fs = require('fs');
-
-var common = require('../../tasks/util/common');
-var getMockList = require('./assets/get_mock_list');
-var getImagePaths = require('./assets/get_image_paths');
-
-/**
- * Image pixel comparison test script.
- *
- * Called by `tasks/test_image.sh in `npm run test-image`.
- *
- * CLI arguments:
- *
- * 1. 'pattern' : glob determining which mock(s) are to be tested
- *
- * Examples:
- *
- * Run all tests:
- *
- * npm run test-image
- *
- * Run the 'contour_nolines' test:
- *
- * npm run test-image -- contour_nolines
- *
- * Run all gl3d image test
- *
- * npm run test-image -- gl3d_*
- *
- */
-
-var argv = minimist(process.argv.slice(2), {});
-
-// If no pattern is provided, all mocks are compared
-if(argv._.length === 0) {
- argv._.push('');
-}
-
-// Build list of mocks to compare
-var allMockList = [];
-var mathjax3;
-var virtualWebgl = false;
-argv._.forEach(function(pattern) {
- if(pattern === 'mathjax3') {
- mathjax3 = true;
- } else if(pattern === 'virtual-webgl') {
- virtualWebgl = true;
- allMockList = getMockList('');
- } else {
- var mockList = getMockList(pattern);
-
- if(mockList.length === 0) {
- throw 'No mocks found with pattern ' + pattern;
- }
-
- allMockList = allMockList.concat(mockList);
- }
-});
-
-var blacklist = [
- 'map_angles',
- 'map_stamen-style',
- 'map_predefined-styles2',
- 'map_scattercluster',
- 'map_fonts-supported-open-sans',
- 'map_fonts-supported-open-sans-weight',
- 'map_layers',
-];
-
-if(virtualWebgl) {
- allMockList = allMockList.filter(function(a) {
- return a.slice(0, 2) === 'gl';
- });
-}
-
-if(mathjax3) {
- allMockList = [
- 'legend_mathjax_title_and_items',
- 'mathjax',
- 'parcats_grid_subplots',
- 'table_latex_multitrace_scatter',
- 'table_plain_birds',
- 'table_wrapped_birds',
- 'ternary-mathjax',
- 'ternary-mathjax-title-place-subtitle',
- ];
-}
-
-// To get rid of duplicates
-function unique(value, index, self) {
- return self.indexOf(value) === index;
-}
-allMockList = allMockList.filter(unique);
-
-var skipped = [];
-var failed = [];
-var fail = function(mockName) {
- if(failed.indexOf(mockName) === -1) {
- failed.push(mockName);
- }
-};
-
-for(var i = 0; i < allMockList.length; i++) {
- var mockName = allMockList[i];
-
- // skip blacklist
- if(blacklist.indexOf(mockName) !== -1) continue;
-
- var flakyMap = [
- // more flaky
- 'map_density0-legend',
- 'map_osm-style',
- 'map_predefined-styles1',
- 'map_predefined-styles2',
- ].indexOf(mockName) !== -1;
-
- var otherFlaky = [
- // list flaky mocks other than maps:
- 'gl3d_bunny-hull'
- ].indexOf(mockName) !== -1;
-
- var threshold =
- flakyMap ? 1 :
- otherFlaky ? 0.15 :
- 0;
-
- if(mathjax3) mockName = 'mathjax3___' + mockName;
-
- var imagePaths = getImagePaths(mockName);
- var base = imagePaths.baseline;
- var test = imagePaths.test;
-
- if(!common.doesFileExist(test) && !mathjax3) {
- console.log('- skip:', mockName);
- skipped.push(mockName);
- continue;
- }
- console.log('+ test:', mockName);
-
- var img0 = PNG.sync.read(fs.readFileSync(base));
- var img1 = PNG.sync.read(fs.readFileSync(test));
- var s0, s1, key;
-
- key = 'width';
- s0 = img0[key];
- s1 = img0[key];
- if(s0 !== s1) {
- console.error(key + 's do not match: ' + s0 + ' vs ' + s1);
- fail(mockName);
- }
-
- key = 'height';
- s0 = img0[key];
- s1 = img0[key];
- if(s0 !== s1) {
- console.error(key + 's do not match: ' + s0 + ' vs ' + s1);
- fail(mockName);
- }
-
- var width = img0.width;
- var height = img0.height;
-
- var diff = new PNG({
- width: width,
- height: height
- });
-
- if(virtualWebgl) {
- threshold = Math.max(0.4, threshold);
- if([
- 'gl3d_ibm-plot',
- 'gl3d_isosurface_2surfaces-checker_spaceframe',
- 'gl3d_opacity-scaling-spikes',
- 'gl3d_cone-wind',
- 'gl3d_isosurface_math',
- 'gl3d_scatter3d-blank-text',
- 'gl3d_mesh3d_surface3d_scatter3d_line3d_error3d_log_reversed_ranges'
- ].indexOf(mockName) !== -1) threshold = 0.7;
- }
-
- var numDiffPixels = pixelmatch(img0.data, img1.data, diff.data, width, height, {
- threshold: threshold
- });
-
- if(numDiffPixels) {
- fs.writeFileSync(imagePaths.diff, PNG.sync.write(diff));
-
- console.error('pixels do not match: ' + numDiffPixels);
- fail(mockName);
- } else {
- // remove when identical
- fs.unlinkSync(imagePaths.test);
- }
-}
-
-if(failed.length || skipped.length) {
- throw JSON.stringify({
- failed: failed,
- skipped: skipped
- }, null, 2);
-}
diff --git a/test/image/compare_pixels_test.mjs b/test/image/compare_pixels_test.mjs
new file mode 100644
index 00000000000..a6b0035bc06
--- /dev/null
+++ b/test/image/compare_pixels_test.mjs
@@ -0,0 +1,177 @@
+import fs from 'fs';
+import minimist from 'minimist';
+import path from 'path';
+import pixelmatch from 'pixelmatch';
+import { PNG } from 'pngjs';
+import { fileURLToPath } from 'url';
+import common from '../../tasks/util/common.js';
+import constants from '../../tasks/util/constants.js';
+import getImagePaths from './assets/get_image_paths.js';
+import getMockList from './assets/get_mock_list.js';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+fs.mkdirSync(constants.pathToTestImagesDiff, { recursive: true });
+
+/**
+ * Image pixel comparison test script.
+ *
+ * Called by `tasks/test_image.sh in `npm run test-image`.
+ *
+ * CLI arguments:
+ *
+ * 1. 'pattern' : glob determining which mock(s) are to be tested
+ *
+ * Examples:
+ *
+ * Run all tests:
+ *
+ * npm run test-image
+ *
+ * Run the 'contour_nolines' test:
+ *
+ * npm run test-image -- contour_nolines
+ *
+ * Run all gl3d image test
+ *
+ * npm run test-image -- gl3d_*
+ *
+ */
+
+const argv = minimist(process.argv.slice(2), {});
+
+// If no pattern is provided, all mocks are compared
+if (argv._.length === 0) argv._.push('');
+
+// Build list of mocks to compare
+let allMockList = [];
+let mathjax3 = false;
+let virtualWebgl = false;
+argv._.forEach((pattern) => {
+ if (pattern === 'mathjax3') {
+ mathjax3 = true;
+ } else if (pattern === 'virtual-webgl') {
+ virtualWebgl = true;
+ allMockList = getMockList('');
+ } else {
+ const mockList = getMockList(pattern);
+ if (mockList.length === 0) throw 'No mocks found with pattern ' + pattern;
+
+ allMockList = allMockList.concat(mockList);
+ }
+});
+
+const skipped = new Set();
+const failed = new Set();
+// TODO: In Node 20+, replace with: import collections from './compare_pixels_collections.json' with { type: 'json' };
+const collectionsPath = path.join(__dirname, 'compare_pixels_collections.json');
+const collections = JSON.parse(fs.readFileSync(collectionsPath));
+const disallowList = new Set(collections.compare_disallow);
+const flakyList = new Set(['gl3d_bunny-hull']);
+const flakyListMaps = new Set([
+ // more flaky
+ 'map_density0-legend',
+ 'map_osm-style',
+ 'map_predefined-styles1',
+ 'map_predefined-styles2'
+]);
+if (virtualWebgl) {
+ allMockList = allMockList.filter((a) => a.startsWith('gl') || a.startsWith('map'));
+}
+
+if (mathjax3) {
+ allMockList = collections.compare_mathjax3;
+}
+allMockList = new Set(allMockList);
+
+for (let mockName of allMockList) {
+ if (disallowList.has(mockName)) continue;
+
+ let threshold;
+ if (flakyListMaps.has(mockName)) threshold = 1;
+ else if (flakyList.has(mockName)) threshold = 0.15;
+ else threshold = 0;
+
+ if (mathjax3) mockName = 'mathjax3___' + mockName;
+ if (virtualWebgl) mockName = 'virtual-webgl___' + mockName;
+
+ const { baseline: base, test, diff } = getImagePaths(mockName);
+
+ if (!common.doesFileExist(test) && !mathjax3) {
+ console.log('- skip:', mockName);
+ skipped.add(mockName);
+ continue;
+ }
+ console.log('+ test:', mockName);
+
+ try {
+ if (!common.doesFileExist(base)) {
+ console.error('baseline image missing');
+ fs.copyFileSync(test, diff);
+ failed.add(mockName);
+ continue;
+ }
+
+ const img0 = PNG.sync.read(fs.readFileSync(base));
+ const img1 = PNG.sync.read(fs.readFileSync(test));
+ let dimensionMismatch = false;
+ for (const key of ['height', 'width']) {
+ const length0 = img0[key];
+ const length1 = img1[key];
+ if (length0 !== length1) {
+ console.error(key + 's do not match: ' + length0 + ' vs ' + length1);
+ dimensionMismatch = true;
+ }
+ }
+
+ if (dimensionMismatch) {
+ fs.copyFileSync(test, diff);
+ failed.add(mockName);
+ continue;
+ }
+
+ const { height, width } = img0;
+ const imageDiff = new PNG({ width, height });
+ const numDiffPixels = pixelmatch(img0.data, img1.data, imageDiff.data, width, height, { threshold });
+
+ if (numDiffPixels) {
+ fs.writeFileSync(diff, PNG.sync.write(imageDiff));
+ console.error('pixels do not match: ' + numDiffPixels);
+ failed.add(mockName);
+ } else {
+ // remove when identical
+ fs.unlinkSync(test);
+ }
+ } catch (e) {
+ console.error('error comparing ' + mockName + ':', e);
+ failed.add(mockName);
+ }
+}
+
+// Debug: list contents of diff folder
+console.log('\n=== build/test_images/ ===');
+try {
+ const testFiles = fs.readdirSync(constants.pathToTestImages);
+ console.log(testFiles.length + ' files:', testFiles.join(', '));
+} catch {
+ console.log('(empty or missing)');
+}
+
+console.log('=== build/test_images_diff/ ===');
+try {
+ const diffFiles = fs.readdirSync(constants.pathToTestImagesDiff);
+ console.log(diffFiles.length + ' files:', diffFiles.join(', '));
+} catch {
+ console.log('(empty or missing)');
+}
+
+if (failed.size || skipped.size) {
+ throw JSON.stringify(
+ {
+ failed: Array.from(failed),
+ skipped: Array.from(skipped)
+ },
+ null,
+ 2
+ );
+}
diff --git a/test/image/make_baseline.py b/test/image/make_baseline.py
index 01dc836da76..a2b00760efb 100644
--- a/test/image/make_baseline.py
+++ b/test/image/make_baseline.py
@@ -5,130 +5,136 @@
from convert_b64 import arraysToB64
args = []
-if len(sys.argv) == 2 :
+if len(sys.argv) == 2:
args = sys.argv[1].split()
-elif len(sys.argv) > 1 :
+elif len(sys.argv) > 1:
args = sys.argv
root = os.getcwd()
-virtual_webgl = os.path.join(root, 'node_modules', 'virtual-webgl', 'src', 'virtual-webgl.js')
-plotlyjs = os.path.join(root, 'build', 'plotly.js')
-plotlyjs_with_virtual_webgl = os.path.join(root, 'build', 'plotly_with_virtual-webgl.js')
+virtual_webgl = os.path.join(
+ root, "node_modules", "virtual-webgl", "src", "virtual-webgl.js"
+)
+plotlyjs = os.path.join(root, "build", "plotly.js")
+plotlyjs_with_virtual_webgl = os.path.join(
+ root, "build", "plotly_with_virtual-webgl.js"
+)
-dirIn = os.path.join(root, 'test', 'image', 'mocks')
-dirOut = os.path.join(root, 'build', 'test_images')
+dirIn = os.path.join(root, "test", "image", "mocks")
+dirOut = os.path.join(root, "build", "test_images")
# N.B. equal is the falg to write to baselines not test_images
-if '=' in args :
- args = args[args.index('=') + 1:]
- dirOut = os.path.join(root, 'test', 'image', 'baselines')
+if "=" in args:
+ args = args[args.index("=") + 1 :]
+ dirOut = os.path.join(root, "test", "image", "baselines")
-if 'mathjax3=' in sys.argv :
- dirOut = os.path.join(root, 'test', 'image', 'baselines')
+if "mathjax3=" in sys.argv:
+ dirOut = os.path.join(root, "test", "image", "baselines")
-print('output to', dirOut)
+print("output to", dirOut)
mathjax_version = 2
-if 'mathjax3' in sys.argv or 'mathjax3=' in sys.argv :
+if "mathjax3" in sys.argv or "mathjax3=" in sys.argv:
# until https://github.com/plotly/Kaleido/issues/124 is addressed
# we are uanble to use local mathjax v3 installed in node_modules
# for now let's download it from the internet:
- pio.kaleido.scope.mathjax = 'https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js'
+ pio.kaleido.scope.mathjax = (
+ "https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js"
+ )
mathjax_version = 3
- print('Kaleido using MathJax v3')
+ print("Kaleido using MathJax v3")
-virtual_webgl_version = 0 # i.e. virtual-webgl is not used
-if 'virtual-webgl' in sys.argv or 'virtual-webgl=' in sys.argv :
+virtual_webgl_version = 0 # i.e. virtual-webgl is not used
+if "virtual-webgl" in sys.argv or "virtual-webgl=" in sys.argv:
virtual_webgl_version = 1
- print('using virtual-webgl for WebGL v1')
+ print("using virtual-webgl for WebGL v1")
- with open(plotlyjs_with_virtual_webgl, 'w') as fileOut:
+ with open(plotlyjs_with_virtual_webgl, "w") as fileOut:
for filename in [virtual_webgl, plotlyjs]:
- with open(filename, 'r') as fileIn:
+ with open(filename, "r") as fileIn:
for line in fileIn:
fileOut.write(line)
plotlyjs = plotlyjs_with_virtual_webgl
pio.kaleido.scope.plotlyjs = plotlyjs
-pio.kaleido.scope.topojson = "file://" + os.path.join(root, 'topojson', 'dist')
-pio.templates.default = 'none'
+pio.kaleido.scope.topojson = "file://" + os.path.join(root, "topojson", "dist")
+pio.templates.default = "none"
-ALL_MOCKS = [os.path.splitext(a)[0] for a in os.listdir(dirIn) if a.endswith('.json')]
+ALL_MOCKS = [os.path.splitext(a)[0] for a in os.listdir(dirIn) if a.endswith(".json")]
ALL_MOCKS.sort()
-if len(args) > 0 :
+if len(args) > 0:
allNames = [a for a in args if a in ALL_MOCKS]
-else :
+else:
allNames = ALL_MOCKS
-# unable to generate baselines for the following mocks
-blacklist = [
- 'map_stamen-style',
- 'map_predefined-styles2',
- 'map_scattercluster',
- 'map_fonts-supported-open-sans',
- 'map_fonts-supported-open-sans-weight',
- 'map_layers',
-]
-allNames = [a for a in allNames if a not in blacklist]
-
-if len(allNames) == 0 :
- print('error: Nothing to create!')
+with open(
+ os.path.join(root, "test", "image", "compare_pixels_collections.json"), "r"
+) as f:
+ # unable to generate baselines for the following mocks
+ disallowList = set(json.load(f)["compare_disallow"])
+allNames = [a for a in allNames if a not in disallowList]
+
+if len(allNames) == 0:
+ print("error: Nothing to create!")
sys.exit(1)
failed = []
-for name in allNames :
+for name in allNames:
outName = name
- if mathjax_version == 3 :
- outName = 'mathjax3___' + name
+ if mathjax_version == 3:
+ outName = "mathjax3___" + name
+ if virtual_webgl_version == 1:
+ outName = "virtual-webgl___" + outName
print(outName)
created = False
- MAX_RETRY = 2 # 1 means retry once
- for attempt in range(0, MAX_RETRY + 1) :
- with open(os.path.join(dirIn, name + '.json'), 'r') as _in :
+ MAX_RETRY = 2 # 1 means retry once
+ for attempt in range(0, MAX_RETRY + 1):
+ with open(os.path.join(dirIn, name + ".json"), "r") as _in:
fig = json.load(_in)
width = 700
height = 500
- if 'layout' in fig :
- layout = fig['layout']
- if 'autosize' not in layout or layout['autosize'] != True :
- if 'width' in layout :
- width = layout['width']
- if 'height' in layout :
- height = layout['height']
-
- if 'b64' in sys.argv or 'b64=' in sys.argv or 'b64-json' in sys.argv :
+ if "layout" in fig:
+ layout = fig["layout"]
+ if "autosize" not in layout or layout["autosize"] != True:
+ if "width" in layout:
+ width = layout["width"]
+ if "height" in layout:
+ height = layout["height"]
+
+ if "b64" in sys.argv or "b64=" in sys.argv or "b64-json" in sys.argv:
newFig = dict()
arraysToB64(fig, newFig)
fig = newFig
- if 'b64-json' in sys.argv and attempt == 0 : print(json.dumps(fig, indent = 2))
+ if "b64-json" in sys.argv and attempt == 0:
+ print(json.dumps(fig, indent=2))
- try :
+ try:
pio.write_image(
fig=fig,
- file=os.path.join(dirOut, outName + '.png'),
+ file=os.path.join(dirOut, outName + ".png"),
width=width,
height=height,
- validate=False
+ validate=False,
)
created = True
- except Exception as e :
+ except Exception as e:
print(e)
- if attempt < MAX_RETRY :
- print('retry', attempt + 1, '/', MAX_RETRY)
- else :
+ if attempt < MAX_RETRY:
+ print("retry", attempt + 1, "/", MAX_RETRY)
+ else:
failed.append(outName)
- if(created) : break
+ if created:
+ break
-if len(failed) > 0 :
- print('Failed at :')
+if len(failed) > 0:
+ print("Failed at :")
print(failed)
sys.exit(1)
diff --git a/test/image/make_exports.py b/test/image/make_exports.py
index 279439af1e4..de23ac74271 100644
--- a/test/image/make_exports.py
+++ b/test/image/make_exports.py
@@ -4,62 +4,63 @@
import plotly.io as pio
root = os.getcwd()
-dirIn = os.path.join(root, 'test', 'image', 'mocks')
-dirOut = os.path.join(root, 'build', 'test_images')
+dirIn = os.path.join(root, "test", "image", "mocks")
+dirOut = os.path.join(root, "build", "test_images")
-pio.templates.default = 'none'
-pio.kaleido.scope.plotlyjs = os.path.join(root, 'build', 'plotly.js')
+pio.templates.default = "none"
+pio.kaleido.scope.plotlyjs = os.path.join(root, "build", "plotly.js")
-allFormats = ['svg', 'jpg', 'jpeg', 'webp', 'pdf']
+allFormats = ["svg", "jpg", "jpeg", "webp", "pdf"]
# 'png' is tested by image-test
allNames = [
- 'plot_types',
- 'annotations',
- 'shapes',
- 'range_slider',
- 'contour_legend-colorscale',
- 'layout_image',
- 'image_astronaut_source',
- 'gl2d_no-clustering2',
- 'gl3d_surface-heatmap-treemap_transparent-colorscale',
- 'map_density-multiple_legend',
- 'smith_modes',
- 'zsmooth_methods',
- 'fonts',
- 'worldcup',
- 'mathjax'
+ "annotations",
+ "contour_legend-colorscale",
+ "fonts",
+ "gl2d_no-clustering2",
+ "gl3d_surface-heatmap-treemap_transparent-colorscale",
+ "image_astronaut_source",
+ "layout_image",
+ "map_density-multiple_legend",
+ "mathjax",
+ "plot_types",
+ "range_slider",
+ "shapes",
+ "smith_modes",
+ "worldcup",
+ "zsmooth_methods",
]
failed = 0
-for name in allNames :
- for fmt in allFormats :
- print(name + ' --> ' + fmt)
+for name in allNames:
+ for fmt in allFormats:
+ print(name + " --> " + fmt)
- with open(os.path.join(dirIn, name + '.json'), 'r') as _in :
+ with open(os.path.join(dirIn, name + ".json"), "r") as _in:
fig = json.load(_in)
width = 700
height = 500
- if 'layout' in fig :
- layout = fig['layout']
- if 'autosize' not in layout or layout['autosize'] != True :
- if 'width' in layout :
- width = layout['width']
- if 'height' in layout :
- height = layout['height']
+ if "layout" in fig:
+ layout = fig["layout"]
+ if "autosize" not in layout or layout["autosize"] != True:
+ if "width" in layout:
+ width = layout["width"]
+ if "height" in layout:
+ height = layout["height"]
- try :
+ try:
pio.write_image(
fig=fig,
- file=os.path.join(dirOut, name + '.' + fmt),
+ file=os.path.join(dirOut, name + "." + fmt),
width=width,
height=height,
- validate=False
+ validate=False,
)
- except Exception as e :
+ except Exception as e:
print(e)
failed += 1
-if failed > 0 : sys.exit(1)
+if failed > 0:
+ sys.exit(1)
diff --git a/test/image/mocks/zz-geo_choropleth-egypt-sudan.json b/test/image/mocks/geo_choropleth-egypt-sudan.json
similarity index 100%
rename from test/image/mocks/zz-geo_choropleth-egypt-sudan.json
rename to test/image/mocks/geo_choropleth-egypt-sudan.json
diff --git a/test/image/mocks/geo_choropleth-usa-location-names.json b/test/image/mocks/geo_choropleth-usa-location-names.json
new file mode 100644
index 00000000000..59495991023
--- /dev/null
+++ b/test/image/mocks/geo_choropleth-usa-location-names.json
@@ -0,0 +1,152 @@
+{
+ "data": [
+ {
+ "autocolorscale": false,
+ "zmax": 16472.88,
+ "colorscale": [
+ [0, "rgb(242,240,247)"],
+ [0.2, "rgb(218,218,235)"],
+ [0.4, "rgb(188,189,220)"],
+ [0.6, "rgb(158,154,200)"],
+ [0.8, "rgb(117,107,177)"],
+ [1, "rgb(84,39,143)"]
+ ],
+ "text": [
+ "Alabama
--
Beef: 34.4
Pork: 10.6
Poultry: 481.0
Dairy: 4.06
--
Fruits: 25.11
Veggies: 14.33
--
Wheat: 70.0
Corn: 34.9
Cotton: 317.61",
+ "Alaska
--
Beef: 0.2
Pork: 0.1
Poultry: 0.0
Dairy: 0.19
--
Fruits: 0.0
Veggies: 1.56
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Arizona
--
Beef: 71.3
Pork: 17.9
Poultry: 0.0
Dairy: 105.48
--
Fruits: 60.27
Veggies: 386.91
--
Wheat: 48.7
Corn: 7.3
Cotton: 423.95",
+ "Arkansas
--
Beef: 53.2
Pork: 29.4
Poultry: 562.9
Dairy: 3.53
--
Fruits: 6.88
Veggies: 11.45
--
Wheat: 114.5
Corn: 69.5
Cotton: 665.44",
+ " California
--
Beef: 228.7
Pork: 11.1
Poultry: 225.4
Dairy: 929.95
--
Fruits: 8736.4
Veggies: 2106.79
--
Wheat: 249.3
Corn: 34.6
Cotton: 1064.95",
+ "Colorado
--
Beef: 261.4
Pork: 66.0
Poultry: 14.0
Dairy: 71.94
--
Fruits: 17.99
Veggies: 118.27
--
Wheat: 400.5
Corn: 183.2
Cotton: 0.0",
+ "Connecticut
--
Beef: 1.1
Pork: 0.1
Poultry: 6.9
Dairy: 9.49
--
Fruits: 13.1
Veggies: 11.16
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Delaware
--
Beef: 0.4
Pork: 0.6
Poultry: 114.7
Dairy: 2.3
--
Fruits: 1.53
Veggies: 20.03
--
Wheat: 22.9
Corn: 26.9
Cotton: 0.0",
+ "Florida
--
Beef: 42.6
Pork: 0.9
Poultry: 56.9
Dairy: 66.31
--
Fruits: 1371.36
Veggies: 450.86
--
Wheat: 1.8
Corn: 3.5
Cotton: 78.24",
+ "Georgia
--
Beef: 31.0
Pork: 18.9
Poultry: 630.4
Dairy: 38.38
--
Fruits: 233.51
Veggies: 154.77
--
Wheat: 65.4
Corn: 57.8
Cotton: 1154.07",
+ "Hawaii
--
Beef: 4.0
Pork: 0.7
Poultry: 1.3
Dairy: 1.16
--
Fruits: 55.51
Veggies: 24.83
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Idaho
--
Beef: 119.8
Pork: 0.0
Poultry: 2.4
Dairy: 294.6
--
Fruits: 21.64
Veggies: 319.19
--
Wheat: 568.2
Corn: 24.0
Cotton: 0.0",
+ "Illinois
--
Beef: 53.7
Pork: 394.0
Poultry: 14.0
Dairy: 45.82
--
Fruits: 12.53
Veggies: 39.95
--
Wheat: 223.8
Corn: 2228.5
Cotton: 0.0",
+ "Indiana
--
Beef: 21.9
Pork: 341.9
Poultry: 165.6
Dairy: 89.7
--
Fruits: 12.98
Veggies: 37.89
--
Wheat: 114.0
Corn: 1123.2
Cotton: 0.0",
+ "Iowa
--
Beef: 289.8
Pork: 1895.6
Poultry: 155.6
Dairy: 107.0
--
Fruits: 3.24
Veggies: 7.1
--
Wheat: 3.1
Corn: 2529.8
Cotton: 0.0",
+ "Kansas
--
Beef: 659.3
Pork: 179.4
Poultry: 6.4
Dairy: 65.45
--
Fruits: 3.11
Veggies: 9.32
--
Wheat: 1426.5
Corn: 457.3
Cotton: 43.98",
+ "Kentucky
--
Beef: 54.8
Pork: 34.2
Poultry: 151.3
Dairy: 28.27
--
Fruits: 6.6
Veggies: 0.0
--
Wheat: 149.3
Corn: 179.1
Cotton: 0.0",
+ "Louisiana
--
Beef: 19.8
Pork: 0.8
Poultry: 77.2
Dairy: 6.02
--
Fruits: 17.83
Veggies: 17.25
--
Wheat: 78.7
Corn: 91.4
Cotton: 280.42",
+ "Maine
--
Beef: 1.4
Pork: 0.5
Poultry: 10.4
Dairy: 16.18
--
Fruits: 52.01
Veggies: 62.9
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Maryland
--
Beef: 5.6
Pork: 3.1
Poultry: 127.0
Dairy: 24.81
--
Fruits: 12.9
Veggies: 20.43
--
Wheat: 55.8
Corn: 54.1
Cotton: 0.0",
+ "Massachusetts
--
Beef: 0.6
Pork: 0.5
Poultry: 0.6
Dairy: 5.81
--
Fruits: 80.83
Veggies: 21.13
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Michigan
--
Beef: 37.7
Pork: 118.1
Poultry: 32.6
Dairy: 214.82
--
Fruits: 257.69
Veggies: 189.96
--
Wheat: 247.0
Corn: 381.5
Cotton: 0.0",
+ "Minnesota
--
Beef: 112.3
Pork: 740.4
Poultry: 189.2
Dairy: 218.05
--
Fruits: 7.91
Veggies: 120.37
--
Wheat: 538.1
Corn: 1264.3
Cotton: 0.0",
+ "Mississippi
--
Beef: 12.8
Pork: 30.4
Poultry: 370.8
Dairy: 5.45
--
Fruits: 17.04
Veggies: 27.87
--
Wheat: 102.2
Corn: 110.0
Cotton: 494.75",
+ "Missouri
--
Beef: 137.2
Pork: 277.3
Poultry: 196.1
Dairy: 34.26
--
Fruits: 13.18
Veggies: 17.9
--
Wheat: 161.7
Corn: 428.8
Cotton: 345.29",
+ "Montana
--
Beef: 105.0
Pork: 16.7
Poultry: 1.7
Dairy: 6.82
--
Fruits: 3.3
Veggies: 45.27
--
Wheat: 1198.1
Corn: 5.4
Cotton: 0.0",
+ "Nebraska
--
Beef: 762.2
Pork: 262.5
Poultry: 31.4
Dairy: 30.07
--
Fruits: 2.16
Veggies: 53.5
--
Wheat: 292.3
Corn: 1735.9
Cotton: 0.0",
+ "Nevada
--
Beef: 21.8
Pork: 0.2
Poultry: 0.0
Dairy: 16.57
--
Fruits: 1.19
Veggies: 27.93
--
Wheat: 5.4
Corn: 0.0
Cotton: 0.0",
+ "New Hampshire
--
Beef: 0.6
Pork: 0.2
Poultry: 0.8
Dairy: 7.46
--
Fruits: 7.98
Veggies: 4.5
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "New Jersey
--
Beef: 0.8
Pork: 0.4
Poultry: 4.6
Dairy: 3.37
--
Fruits: 109.45
Veggies: 56.54
--
Wheat: 6.7
Corn: 10.1
Cotton: 0.0",
+ "New Mexico
--
Beef: 117.2
Pork: 0.1
Poultry: 0.3
Dairy: 191.01
--
Fruits: 101.9
Veggies: 43.88
--
Wheat: 13.9
Corn: 11.2
Cotton: 72.62",
+ "New York
--
Beef: 22.2
Pork: 5.8
Poultry: 17.7
Dairy: 331.8
--
Fruits: 202.56
Veggies: 143.37
--
Wheat: 29.9
Corn: 106.1
Cotton: 0.0",
+ "North Carolina
--
Beef: 24.8
Pork: 702.8
Poultry: 598.4
Dairy: 24.9
--
Fruits: 74.47
Veggies: 150.45
--
Wheat: 200.3
Corn: 92.2
Cotton: 470.86",
+ "North Dakota
--
Beef: 78.5
Pork: 16.1
Poultry: 0.5
Dairy: 8.14
--
Fruits: 0.25
Veggies: 130.79
--
Wheat: 1664.5
Corn: 236.1
Cotton: 0.0",
+ "Ohio
--
Beef: 36.2
Pork: 199.1
Poultry: 129.9
Dairy: 134.57
--
Fruits: 27.21
Veggies: 53.53
--
Wheat: 207.4
Corn: 535.1
Cotton: 0.0",
+ "Oklahoma
--
Beef: 337.6
Pork: 265.3
Poultry: 131.1
Dairy: 24.35
--
Fruits: 9.24
Veggies: 8.9
--
Wheat: 324.8
Corn: 27.5
Cotton: 110.54",
+ "Oregon
--
Beef: 58.8
Pork: 1.4
Poultry: 14.2
Dairy: 63.66
--
Fruits: 315.04
Veggies: 126.5
--
Wheat: 320.3
Corn: 11.7
Cotton: 0.0",
+ "Pennsylvania
--
Beef: 50.9
Pork: 91.3
Poultry: 169.8
Dairy: 280.87
--
Fruits: 89.48
Veggies: 38.26
--
Wheat: 41.0
Corn: 112.1
Cotton: 0.0",
+ "Rhode Island
--
Beef: 0.1
Pork: 0.1
Poultry: 0.2
Dairy: 0.52
--
Fruits: 2.83
Veggies: 3.02
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "South Carolina
--
Beef: 15.2
Pork: 10.9
Poultry: 186.5
Dairy: 7.62
--
Fruits: 53.45
Veggies: 42.66
--
Wheat: 55.3
Corn: 32.1
Cotton: 206.1",
+ "South Dakota
--
Beef: 193.5
Pork: 160.2
Poultry: 29.3
Dairy: 46.77
--
Fruits: 0.8
Veggies: 4.06
--
Wheat: 704.5
Corn: 643.6
Cotton: 0.0",
+ "Tennessee
--
Beef: 51.1
Pork: 17.6
Poultry: 82.4
Dairy: 21.18
--
Fruits: 6.23
Veggies: 24.67
--
Wheat: 100.0
Corn: 88.8
Cotton: 363.83",
+ "Texas
--
Beef: 961.0
Pork: 42.7
Poultry: 339.2
Dairy: 240.55
--
Fruits: 99.9
Veggies: 115.23
--
Wheat: 309.7
Corn: 167.2
Cotton: 2308.76",
+ "Utah
--
Beef: 27.9
Pork: 59.0
Poultry: 23.1
Dairy: 48.6
--
Fruits: 12.34
Veggies: 6.6
--
Wheat: 42.8
Corn: 5.3
Cotton: 0.0",
+ "Vermont
--
Beef: 6.2
Pork: 0.2
Poultry: 0.9
Dairy: 65.98
--
Fruits: 8.01
Veggies: 4.05
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
+ "Virginia
--
Beef: 39.5
Pork: 16.9
Poultry: 164.7
Dairy: 47.85
--
Fruits: 36.48
Veggies: 27.25
--
Wheat: 77.5
Corn: 39.5
Cotton: 64.84",
+ "Washington
--
Beef: 59.2
Pork: 0.0
Poultry: 35.6
Dairy: 154.18
--
Fruits: 1738.57
Veggies: 363.79
--
Wheat: 786.3
Corn: 29.5
Cotton: 0.0",
+ "West Virginia
--
Beef: 12.0
Pork: 0.3
Poultry: 45.4
Dairy: 3.9
--
Fruits: 11.54
Veggies: 0.0
--
Wheat: 1.6
Corn: 3.5
Cotton: 0.0",
+ "Wisconsin
--
Beef: 107.3
Pork: 38.6
Poultry: 34.5
Dairy: 633.6
--
Fruits: 133.8
Veggies: 148.99
--
Wheat: 96.7
Corn: 460.5
Cotton: 0.0",
+ "Wyoming
--
Beef: 75.1
Pork: 33.2
Poultry: 0.1
Dairy: 2.89
--
Fruits: 0.17
Veggies: 10.23
--
Wheat: 20.7
Corn: 9.0
Cotton: 0.0"
+ ],
+ "zmin": 13.31,
+ "locations": [
+ "AL",
+ "AK",
+ "AZ",
+ "AR",
+ "CA",
+ "CO",
+ "CT",
+ "DE",
+ "FL",
+ "GA",
+ "HI",
+ "ID",
+ "IL",
+ "IN",
+ "IA",
+ "KS",
+ "KY",
+ "LA",
+ "ME",
+ "MD",
+ "MA",
+ "MI",
+ "MN",
+ "MS",
+ "MO",
+ "MT",
+ "NE",
+ "NV",
+ "NH",
+ "NJ",
+ "NM",
+ "NY",
+ "NC",
+ "ND",
+ "OH",
+ "OK",
+ "OR",
+ "PA",
+ "RI",
+ "SC",
+ "SD",
+ "TN",
+ "TX",
+ "UT",
+ "VT",
+ "VA",
+ "WA",
+ "WV",
+ "WI",
+ "WY"
+ ],
+ "colorbar": {
+ "title": { "text": "Millions USD" }
+ },
+ "type": "choropleth",
+ "z": [
+ 1390.63, 13.31, 1463.17, 3586.02, 16472.88, 1851.33, 259.62, 282.19,
+ 3764.09, 2860.84, 401.84, 2078.89, 8709.48, 5050.23, 11273.76, 4589.01,
+ 1889.15, 1914.23, 278.37, 692.75, 248.65, 3164.16, 7192.33, 2170.8,
+ 3933.42, 1718, 7114.13, 139.89, 73.06, 500.4, 751.58, 1488.9, 3806.05,
+ 3761.96, 3979.79, 1646.41, 1794.57, 1969.87, 31.59, 929.93, 3770.19,
+ 1535.13, 6648.22, 453.39, 180.14, 1146.48, 3894.81, 138.89, 3090.23,
+ 349.69
+ ],
+ "locationmode": "USA-states"
+ }
+ ],
+ "layout": {
+ "autosize": true,
+ "title": {
+ "text": "2011 US Agriculture Exports by State - Location Names
(Hover for breakdown)"
+ },
+ "showlegend": false,
+ "height": 598,
+ "width": 870,
+ "geo": {
+ "showlakes": true,
+ "scope": "usa",
+ "projection": {
+ "type": "albers usa"
+ },
+ "lakecolor": "rgb(255, 255, 255)"
+ }
+ }
+}
diff --git a/test/image/mocks/geo_choropleth-usa.json b/test/image/mocks/geo_choropleth-usa.json
index 88329cbb828..b3a2255a730 100644
--- a/test/image/mocks/geo_choropleth-usa.json
+++ b/test/image/mocks/geo_choropleth-usa.json
@@ -2,13 +2,6 @@
"data": [
{
"autocolorscale": false,
- "colorbar": {
- "title": { "text": "Millions USD" }
- },
- "locationmode": "USA-states",
- "name": "",
- "type": "choropleth",
- "zmin": 13.31,
"zmax": 16472.88,
"colorscale": [
[0, "rgb(242,240,247)"],
@@ -70,6 +63,7 @@
"Wisconsin
--
Beef: 107.3
Pork: 38.6
Poultry: 34.5
Dairy: 633.6
--
Fruits: 133.8
Veggies: 148.99
--
Wheat: 96.7
Corn: 460.5
Cotton: 0.0",
"Wyoming
--
Beef: 75.1
Pork: 33.2
Poultry: 0.1
Dairy: 2.89
--
Fruits: 0.17
Veggies: 10.23
--
Wheat: 20.7
Corn: 9.0
Cotton: 0.0"
],
+ "zmin": 13.31,
"locations": [
"AL",
"AK",
@@ -122,137 +116,10 @@
"WI",
"WY"
],
- "z": [
- 1390.63, 13.31, 1463.17, 3586.02, 16472.88, 1851.33, 259.62, 282.19,
- 3764.09, 2860.84, 401.84, 2078.89, 8709.48, 5050.23, 11273.76, 4589.01,
- 1889.15, 1914.23, 278.37, 692.75, 248.65, 3164.16, 7192.33, 2170.8,
- 3933.42, 1718, 7114.13, 139.89, 73.06, 500.4, 751.58, 1488.9, 3806.05,
- 3761.96, 3979.79, 1646.41, 1794.57, 1969.87, 31.59, 929.93, 3770.19,
- 1535.13, 6648.22, 453.39, 180.14, 1146.48, 3894.81, 138.89, 3090.23,
- 349.69
- ]
- },
- {
- "autocolorscale": false,
- "geo": "geo2",
- "locationmode": "USA-states",
- "name": "",
- "showscale": false,
+ "colorbar": {
+ "title": { "text": "Millions USD" }
+ },
"type": "choropleth",
- "zmax": 16472.88,
- "zmin": 13.31,
- "colorscale": [
- [0, "rgb(242,240,247)"],
- [0.2, "rgb(218,218,235)"],
- [0.4, "rgb(188,189,220)"],
- [0.6, "rgb(158,154,200)"],
- [0.8, "rgb(117,107,177)"],
- [1, "rgb(84,39,143)"]
- ],
- "text": [
- "Alabama
--
Beef: 34.4
Pork: 10.6
Poultry: 481.0
Dairy: 4.06
--
Fruits: 25.11
Veggies: 14.33
--
Wheat: 70.0
Corn: 34.9
Cotton: 317.61",
- "Alaska
--
Beef: 0.2
Pork: 0.1
Poultry: 0.0
Dairy: 0.19
--
Fruits: 0.0
Veggies: 1.56
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "Arizona
--
Beef: 71.3
Pork: 17.9
Poultry: 0.0
Dairy: 105.48
--
Fruits: 60.27
Veggies: 386.91
--
Wheat: 48.7
Corn: 7.3
Cotton: 423.95",
- "Arkansas
--
Beef: 53.2
Pork: 29.4
Poultry: 562.9
Dairy: 3.53
--
Fruits: 6.88
Veggies: 11.45
--
Wheat: 114.5
Corn: 69.5
Cotton: 665.44",
- " California
--
Beef: 228.7
Pork: 11.1
Poultry: 225.4
Dairy: 929.95
--
Fruits: 8736.4
Veggies: 2106.79
--
Wheat: 249.3
Corn: 34.6
Cotton: 1064.95",
- "Colorado
--
Beef: 261.4
Pork: 66.0
Poultry: 14.0
Dairy: 71.94
--
Fruits: 17.99
Veggies: 118.27
--
Wheat: 400.5
Corn: 183.2
Cotton: 0.0",
- "Connecticut
--
Beef: 1.1
Pork: 0.1
Poultry: 6.9
Dairy: 9.49
--
Fruits: 13.1
Veggies: 11.16
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "Delaware
--
Beef: 0.4
Pork: 0.6
Poultry: 114.7
Dairy: 2.3
--
Fruits: 1.53
Veggies: 20.03
--
Wheat: 22.9
Corn: 26.9
Cotton: 0.0",
- "Florida
--
Beef: 42.6
Pork: 0.9
Poultry: 56.9
Dairy: 66.31
--
Fruits: 1371.36
Veggies: 450.86
--
Wheat: 1.8
Corn: 3.5
Cotton: 78.24",
- "Georgia
--
Beef: 31.0
Pork: 18.9
Poultry: 630.4
Dairy: 38.38
--
Fruits: 233.51
Veggies: 154.77
--
Wheat: 65.4
Corn: 57.8
Cotton: 1154.07",
- "Hawaii
--
Beef: 4.0
Pork: 0.7
Poultry: 1.3
Dairy: 1.16
--
Fruits: 55.51
Veggies: 24.83
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "Idaho
--
Beef: 119.8
Pork: 0.0
Poultry: 2.4
Dairy: 294.6
--
Fruits: 21.64
Veggies: 319.19
--
Wheat: 568.2
Corn: 24.0
Cotton: 0.0",
- "Illinois
--
Beef: 53.7
Pork: 394.0
Poultry: 14.0
Dairy: 45.82
--
Fruits: 12.53
Veggies: 39.95
--
Wheat: 223.8
Corn: 2228.5
Cotton: 0.0",
- "Indiana
--
Beef: 21.9
Pork: 341.9
Poultry: 165.6
Dairy: 89.7
--
Fruits: 12.98
Veggies: 37.89
--
Wheat: 114.0
Corn: 1123.2
Cotton: 0.0",
- "Iowa
--
Beef: 289.8
Pork: 1895.6
Poultry: 155.6
Dairy: 107.0
--
Fruits: 3.24
Veggies: 7.1
--
Wheat: 3.1
Corn: 2529.8
Cotton: 0.0",
- "Kansas
--
Beef: 659.3
Pork: 179.4
Poultry: 6.4
Dairy: 65.45
--
Fruits: 3.11
Veggies: 9.32
--
Wheat: 1426.5
Corn: 457.3
Cotton: 43.98",
- "Kentucky
--
Beef: 54.8
Pork: 34.2
Poultry: 151.3
Dairy: 28.27
--
Fruits: 6.6
Veggies: 0.0
--
Wheat: 149.3
Corn: 179.1
Cotton: 0.0",
- "Louisiana
--
Beef: 19.8
Pork: 0.8
Poultry: 77.2
Dairy: 6.02
--
Fruits: 17.83
Veggies: 17.25
--
Wheat: 78.7
Corn: 91.4
Cotton: 280.42",
- "Maine
--
Beef: 1.4
Pork: 0.5
Poultry: 10.4
Dairy: 16.18
--
Fruits: 52.01
Veggies: 62.9
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "Maryland
--
Beef: 5.6
Pork: 3.1
Poultry: 127.0
Dairy: 24.81
--
Fruits: 12.9
Veggies: 20.43
--
Wheat: 55.8
Corn: 54.1
Cotton: 0.0",
- "Massachusetts
--
Beef: 0.6
Pork: 0.5
Poultry: 0.6
Dairy: 5.81
--
Fruits: 80.83
Veggies: 21.13
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "Michigan
--
Beef: 37.7
Pork: 118.1
Poultry: 32.6
Dairy: 214.82
--
Fruits: 257.69
Veggies: 189.96
--
Wheat: 247.0
Corn: 381.5
Cotton: 0.0",
- "Minnesota
--
Beef: 112.3
Pork: 740.4
Poultry: 189.2
Dairy: 218.05
--
Fruits: 7.91
Veggies: 120.37
--
Wheat: 538.1
Corn: 1264.3
Cotton: 0.0",
- "Mississippi
--
Beef: 12.8
Pork: 30.4
Poultry: 370.8
Dairy: 5.45
--
Fruits: 17.04
Veggies: 27.87
--
Wheat: 102.2
Corn: 110.0
Cotton: 494.75",
- "Missouri
--
Beef: 137.2
Pork: 277.3
Poultry: 196.1
Dairy: 34.26
--
Fruits: 13.18
Veggies: 17.9
--
Wheat: 161.7
Corn: 428.8
Cotton: 345.29",
- "Montana
--
Beef: 105.0
Pork: 16.7
Poultry: 1.7
Dairy: 6.82
--
Fruits: 3.3
Veggies: 45.27
--
Wheat: 1198.1
Corn: 5.4
Cotton: 0.0",
- "Nebraska
--
Beef: 762.2
Pork: 262.5
Poultry: 31.4
Dairy: 30.07
--
Fruits: 2.16
Veggies: 53.5
--
Wheat: 292.3
Corn: 1735.9
Cotton: 0.0",
- "Nevada
--
Beef: 21.8
Pork: 0.2
Poultry: 0.0
Dairy: 16.57
--
Fruits: 1.19
Veggies: 27.93
--
Wheat: 5.4
Corn: 0.0
Cotton: 0.0",
- "New Hampshire
--
Beef: 0.6
Pork: 0.2
Poultry: 0.8
Dairy: 7.46
--
Fruits: 7.98
Veggies: 4.5
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "New Jersey
--
Beef: 0.8
Pork: 0.4
Poultry: 4.6
Dairy: 3.37
--
Fruits: 109.45
Veggies: 56.54
--
Wheat: 6.7
Corn: 10.1
Cotton: 0.0",
- "New Mexico
--
Beef: 117.2
Pork: 0.1
Poultry: 0.3
Dairy: 191.01
--
Fruits: 101.9
Veggies: 43.88
--
Wheat: 13.9
Corn: 11.2
Cotton: 72.62",
- "New York
--
Beef: 22.2
Pork: 5.8
Poultry: 17.7
Dairy: 331.8
--
Fruits: 202.56
Veggies: 143.37
--
Wheat: 29.9
Corn: 106.1
Cotton: 0.0",
- "North Carolina
--
Beef: 24.8
Pork: 702.8
Poultry: 598.4
Dairy: 24.9
--
Fruits: 74.47
Veggies: 150.45
--
Wheat: 200.3
Corn: 92.2
Cotton: 470.86",
- "North Dakota
--
Beef: 78.5
Pork: 16.1
Poultry: 0.5
Dairy: 8.14
--
Fruits: 0.25
Veggies: 130.79
--
Wheat: 1664.5
Corn: 236.1
Cotton: 0.0",
- "Ohio
--
Beef: 36.2
Pork: 199.1
Poultry: 129.9
Dairy: 134.57
--
Fruits: 27.21
Veggies: 53.53
--
Wheat: 207.4
Corn: 535.1
Cotton: 0.0",
- "Oklahoma
--
Beef: 337.6
Pork: 265.3
Poultry: 131.1
Dairy: 24.35
--
Fruits: 9.24
Veggies: 8.9
--
Wheat: 324.8
Corn: 27.5
Cotton: 110.54",
- "Oregon
--
Beef: 58.8
Pork: 1.4
Poultry: 14.2
Dairy: 63.66
--
Fruits: 315.04
Veggies: 126.5
--
Wheat: 320.3
Corn: 11.7
Cotton: 0.0",
- "Pennsylvania
--
Beef: 50.9
Pork: 91.3
Poultry: 169.8
Dairy: 280.87
--
Fruits: 89.48
Veggies: 38.26
--
Wheat: 41.0
Corn: 112.1
Cotton: 0.0",
- "Rhode Island
--
Beef: 0.1
Pork: 0.1
Poultry: 0.2
Dairy: 0.52
--
Fruits: 2.83
Veggies: 3.02
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "South Carolina
--
Beef: 15.2
Pork: 10.9
Poultry: 186.5
Dairy: 7.62
--
Fruits: 53.45
Veggies: 42.66
--
Wheat: 55.3
Corn: 32.1
Cotton: 206.1",
- "South Dakota
--
Beef: 193.5
Pork: 160.2
Poultry: 29.3
Dairy: 46.77
--
Fruits: 0.8
Veggies: 4.06
--
Wheat: 704.5
Corn: 643.6
Cotton: 0.0",
- "Tennessee
--
Beef: 51.1
Pork: 17.6
Poultry: 82.4
Dairy: 21.18
--
Fruits: 6.23
Veggies: 24.67
--
Wheat: 100.0
Corn: 88.8
Cotton: 363.83",
- "Texas
--
Beef: 961.0
Pork: 42.7
Poultry: 339.2
Dairy: 240.55
--
Fruits: 99.9
Veggies: 115.23
--
Wheat: 309.7
Corn: 167.2
Cotton: 2308.76",
- "Utah
--
Beef: 27.9
Pork: 59.0
Poultry: 23.1
Dairy: 48.6
--
Fruits: 12.34
Veggies: 6.6
--
Wheat: 42.8
Corn: 5.3
Cotton: 0.0",
- "Vermont
--
Beef: 6.2
Pork: 0.2
Poultry: 0.9
Dairy: 65.98
--
Fruits: 8.01
Veggies: 4.05
--
Wheat: 0.0
Corn: 0.0
Cotton: 0.0",
- "Virginia
--
Beef: 39.5
Pork: 16.9
Poultry: 164.7
Dairy: 47.85
--
Fruits: 36.48
Veggies: 27.25
--
Wheat: 77.5
Corn: 39.5
Cotton: 64.84",
- "Washington
--
Beef: 59.2
Pork: 0.0
Poultry: 35.6
Dairy: 154.18
--
Fruits: 1738.57
Veggies: 363.79
--
Wheat: 786.3
Corn: 29.5
Cotton: 0.0",
- "West Virginia
--
Beef: 12.0
Pork: 0.3
Poultry: 45.4
Dairy: 3.9
--
Fruits: 11.54
Veggies: 0.0
--
Wheat: 1.6
Corn: 3.5
Cotton: 0.0",
- "Wisconsin
--
Beef: 107.3
Pork: 38.6
Poultry: 34.5
Dairy: 633.6
--
Fruits: 133.8
Veggies: 148.99
--
Wheat: 96.7
Corn: 460.5
Cotton: 0.0",
- "Wyoming
--
Beef: 75.1
Pork: 33.2
Poultry: 0.1
Dairy: 2.89
--
Fruits: 0.17
Veggies: 10.23
--
Wheat: 20.7
Corn: 9.0
Cotton: 0.0"
- ],
- "locations": [
- "Alabama",
- "Alaska",
- "Arizona",
- "Arkansas",
- "California",
- "Colorado",
- "Connecticut",
- "Delaware",
- "Florida",
- "Georgia",
- "Hawaii",
- "Idaho",
- "Illinois",
- "Indiana",
- "Iowa",
- "Kansas",
- "Kentucky",
- "Louisiana",
- "Maine",
- "Maryland",
- "Massachusetts",
- "Michigan",
- "Minnesota",
- "Mississippi",
- "Missouri",
- "Montana",
- "Nebraska",
- "Nevada",
- "New Hampshire",
- "New Jersey",
- "New Mexico",
- "New York",
- "North Carolina",
- "North Dakota",
- "Ohio",
- "Oklahoma",
- "Oregon",
- "Pennsylvania",
- "Rhode Island",
- "South Carolina",
- "South Dakota",
- "Tennessee",
- "Texas",
- "Utah",
- "Vermont",
- "Virginia",
- "Washington",
- "West Virginia",
- "Wisconsin",
- "Wyoming"
- ],
"z": [
1390.63, 13.31, 1463.17, 3586.02, 16472.88, 1851.33, 259.62, 282.19,
3764.09, 2860.84, 401.84, 2078.89, 8709.48, 5050.23, 11273.76, 4589.01,
@@ -261,16 +128,17 @@
3761.96, 3979.79, 1646.41, 1794.57, 1969.87, 31.59, 929.93, 3770.19,
1535.13, 6648.22, 453.39, 180.14, 1146.48, 3894.81, 138.89, 3090.23,
349.69
- ]
+ ],
+ "locationmode": "USA-states"
}
],
"layout": {
"autosize": true,
"title": {
- "text": "2011 US Agriculture Exports by State
(Hover for breakdown)"
+ "text": "2011 US Agriculture Exports by State - Two Letter Abbreviations
(Hover for breakdown)"
},
"showlegend": false,
- "height": 1200,
+ "height": 598,
"width": 870,
"geo": {
"showlakes": true,
@@ -278,37 +146,7 @@
"projection": {
"type": "albers usa"
},
- "lakecolor": "rgb(255, 255, 255)",
- "domain": { "y": [0.55, 1] }
- },
- "geo2": {
- "showlakes": true,
- "scope": "usa",
- "projection": {
- "type": "albers usa"
- },
- "lakecolor": "rgb(255, 255, 255)",
- "domain": { "y": [0, 0.45] }
- },
- "annotations": [
- {
- "text": "Lookup by two letter location abbreviation",
- "x": 0.5,
- "y": 0.53,
- "xref": "paper",
- "yref": "paper",
- "showarrow": false,
- "font": { "size": 16 }
- },
- {
- "text": "Lookup by full location name",
- "x": 0.5,
- "y": -0.02,
- "xref": "paper",
- "yref": "paper",
- "showarrow": false,
- "font": { "size": 16 }
- }
- ]
+ "lakecolor": "rgb(255, 255, 255)"
+ }
}
}
diff --git a/test/image/mocks/zz-label-spacing.json b/test/image/mocks/label-spacing.json
similarity index 100%
rename from test/image/mocks/zz-label-spacing.json
rename to test/image/mocks/label-spacing.json
diff --git a/test/image/mocks/zz-legend-vertical-maxheight.json b/test/image/mocks/legend-vertical-maxheight.json
similarity index 100%
rename from test/image/mocks/zz-legend-vertical-maxheight.json
rename to test/image/mocks/legend-vertical-maxheight.json
diff --git a/test/image/mocks/zz-minorloglabels.json b/test/image/mocks/minorloglabels.json
similarity index 100%
rename from test/image/mocks/zz-minorloglabels.json
rename to test/image/mocks/minorloglabels.json
diff --git a/test/image/mocks/zz-pattern_bars-path.json b/test/image/mocks/pattern_bars-path.json
similarity index 100%
rename from test/image/mocks/zz-pattern_bars-path.json
rename to test/image/mocks/pattern_bars-path.json
diff --git a/test/image/mocks/zz-pie-slice-legend.json b/test/image/mocks/pie-slice-legend.json
similarity index 100%
rename from test/image/mocks/zz-pie-slice-legend.json
rename to test/image/mocks/pie-slice-legend.json
diff --git a/test/image/mocks/zz-pie-slice-legend2.json b/test/image/mocks/pie-slice-legend2.json
similarity index 100%
rename from test/image/mocks/zz-pie-slice-legend2.json
rename to test/image/mocks/pie-slice-legend2.json
diff --git a/test/image/mocks/zz-pie-slice-legend3.json b/test/image/mocks/pie-slice-legend3.json
similarity index 100%
rename from test/image/mocks/zz-pie-slice-legend3.json
rename to test/image/mocks/pie-slice-legend3.json
diff --git a/test/image/mocks/zz-scatter_marker_line_dash.json b/test/image/mocks/scatter_marker_line_dash.json
similarity index 100%
rename from test/image/mocks/zz-scatter_marker_line_dash.json
rename to test/image/mocks/scatter_marker_line_dash.json
diff --git a/test/image/mocks/zz_shapes_clipping_double_digit_subplots.json b/test/image/mocks/shapes_clipping_double_digit_subplots.json
similarity index 100%
rename from test/image/mocks/zz_shapes_clipping_double_digit_subplots.json
rename to test/image/mocks/shapes_clipping_double_digit_subplots.json
diff --git a/test/image/mocks/zz-tickson_boundaries_ticklabelposition.json b/test/image/mocks/tickson_boundaries_ticklabelposition.json
similarity index 100%
rename from test/image/mocks/zz-tickson_boundaries_ticklabelposition.json
rename to test/image/mocks/tickson_boundaries_ticklabelposition.json
diff --git a/test/image/mocks/zzz_zerolinelayer_above.json b/test/image/mocks/zerolinelayer_above.json
similarity index 100%
rename from test/image/mocks/zzz_zerolinelayer_above.json
rename to test/image/mocks/zerolinelayer_above.json
diff --git a/test/image/mocks/zzz_zerolinelayer_below.json b/test/image/mocks/zerolinelayer_below.json
similarity index 100%
rename from test/image/mocks/zzz_zerolinelayer_below.json
rename to test/image/mocks/zerolinelayer_below.json
diff --git a/test/jasmine/karma.conf.js b/test/jasmine/karma.conf.js
index 2c7f075c3ee..cc42795d29f 100644
--- a/test/jasmine/karma.conf.js
+++ b/test/jasmine/karma.conf.js
@@ -38,7 +38,7 @@ var argv = minimist(process.argv.slice(4), {
failFast: false,
doNotFailOnEmptyTestSuite: false,
width: '1035',
- height: '617',
+ height: '800',
verbose: false,
showSkipped: isCI
}
diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js
index 4d85a14fc37..6b336cb0c5c 100644
--- a/test/jasmine/tests/axes_test.js
+++ b/test/jasmine/tests/axes_test.js
@@ -1722,13 +1722,13 @@ describe('Test axes', function() {
width: 600,
height: 600
}).then(function() {
- expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.110, 2]);
+ expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.12, 2]);
return Plotly.relayout(gd, {
'xaxis.insiderange': [1, 3]
});
}).then(function() {
- expect(gd._fullLayout.xaxis.range).toBeCloseToArray([0.889, 3]);
+ expect(gd._fullLayout.xaxis.range).toBeCloseToArray([0.879, 3]);
}).then(done, done.fail);
});
});
@@ -8152,11 +8152,11 @@ describe('more react tests', function() {
Plotly.newPlot(gd, fig1)
.then(function() {
- expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.110, 2]);
+ expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.12, 2]);
return Plotly.react(gd, fig2);
}).then(function() {
- expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.164, 2]);
+ expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.173, 2]);
}).then(done, done.fail);
});
});
diff --git a/test/jasmine/tests/geo_test.js b/test/jasmine/tests/geo_test.js
index 83d0f92a4c2..6faddf3c630 100644
--- a/test/jasmine/tests/geo_test.js
+++ b/test/jasmine/tests/geo_test.js
@@ -1404,7 +1404,7 @@ describe('Test geo interactions', function() {
py -= 2;
mouseEvent('mousemove', px, py);
- if(py > 175) {
+ if(py > 176) {
_assert('- py ' + py, 1);
expect(cnt).toBe(0, 'no plotly_unhover event so far');
} else {
@@ -2608,7 +2608,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
_assert('base', [
[-96.6, 38.7], 1,
], [
- [410, 329], 738.5
+ [410, 309], 738.5
], undefined);
return drag({path: [[250, 250], [200, 200]], noCover: true});
})
@@ -2616,7 +2616,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
_assert('after NW-SE drag', [
[-91.8, 34.8], 1,
], [
- [366, 279], 738.5
+ [366, 259], 738.5
], [
'geo.center.lon', 'geo.center.lon'
]);
@@ -2626,7 +2626,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
_assert('after scroll', [
[-94.5, 35.0], 1.3
], [
- [380, 273], 974.4
+ [380, 245.9], 974.4
], [
'geo.center.lon', 'geo.center.lon', 'geo.projection.scale'
]);
@@ -2637,7 +2637,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
[-94.5, 35.0], 1.3
], [
// new center values are reflected in translate()
- [380, 273], 974.4
+ [380, 245.9], 974.4
], [
'geo.showlakes'
]);
@@ -2647,7 +2647,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
_assert('after double click', [
[-96.6, 38.7], 1,
], [
- [416, 329], 738.5
+ [416, 309], 738.5
], 'dblclick');
})
.then(done, done.fail);
@@ -2759,10 +2759,10 @@ describe('Test geo interactions update marker angles:', function() {
})
.then(function() {
newPath = getPath();
- expect(newPath).toEqual('M0,0L18.224184922503092,8.238876374264322L19.586365339190138,-4.046516131164082Z');
+ expect(newPath).toEqual('M0,0L18.27769005891461,8.119485581627321L19.559475756661865,-4.174554841483899Z');
expect(newPath).not.toEqual(initialPath);
- expect(newPath).toEqual('M0,0L18.224184922503092,8.238876374264322L19.586365339190138,-4.046516131164082Z');
+ expect(newPath).toEqual('M0,0L18.27769005891461,8.119485581627321L19.559475756661865,-4.174554841483899Z');
expect(initialPath).toEqual('M0,0L-1.5094067529528923,19.942960945008643L10.501042615957648,17.021401351764233Z');
})
.then(done, done.fail);
diff --git a/test/jasmine/tests/sankey_test.js b/test/jasmine/tests/sankey_test.js
index 76fa0e9f27c..69120330795 100644
--- a/test/jasmine/tests/sankey_test.js
+++ b/test/jasmine/tests/sankey_test.js
@@ -1144,10 +1144,17 @@ describe('sankey tests', function() {
return function(elType) {
return new Promise(function(resolve, reject) {
- gd.once(eventType, function(d) {
+ const handler = (d) => {
Lib.clearThrottle();
+ const isNode = d.points[0].hasOwnProperty('sourceLinks');
+ const isExpectedType = (elType === 'node') ? isNode : !isNode;
+ if (!isExpectedType) {
+ gd.once(eventType, handler);
+ return;
+ }
resolve(d);
- });
+ }
+ gd.once(eventType, handler);
mouseFn(posByElementType[elType]);
setTimeout(function() {
@@ -1460,8 +1467,8 @@ describe('sankey tests', function() {
nodes = document.getElementsByClassName('sankey-node');
node = Array.prototype.slice.call(nodes).find(function(n) { return n.textContent === '0';});
var newPosition = getNodeCoords(node);
- expect(newPosition.x).toBeCloseTo(positionAfterDrag[0], 2, 'final x position is off');
- expect(newPosition.y).toBeCloseTo(positionAfterDrag[1], 2, 'final y position is off');
+ expect(newPosition.x).toBeCloseTo(positionAfterDrag[0], -1, 'final x position is off');
+ expect(newPosition.y).toBeCloseTo(positionAfterDrag[1], -1, 'final y position is off');
// Change color of nodes
var mockCopy = Lib.extendDeep({}, mockCircularFreeform);
@@ -1485,8 +1492,8 @@ describe('sankey tests', function() {
pos = positionBeforeDrag;
msg = 'should go back to its default because uirevision changed';
}
- expect(newPosition.x).toBeCloseTo(pos[0], 2, 'x position ' + msg);
- expect(newPosition.y).toBeCloseTo(pos[1], 2, 'y position ' + msg);
+ expect(newPosition.x).toBeCloseTo(pos[0], -1, 'x position ' + msg);
+ expect(newPosition.y).toBeCloseTo(pos[1], -1, 'y position ' + msg);
})
.then(done, done.fail);
});
diff --git a/test/jasmine/tests/scatter3d_test.js b/test/jasmine/tests/scatter3d_test.js
index ea6916ae435..a5f1a7f8b4d 100644
--- a/test/jasmine/tests/scatter3d_test.js
+++ b/test/jasmine/tests/scatter3d_test.js
@@ -204,7 +204,6 @@ describe('Test scatter3d interactions:', function() {
}
Plotly.newPlot(gd, _mock)
- .then(delay(20))
.then(function() {
assertObjects(order0);
diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js
index 194c91cdc69..2261a72b24b 100644
--- a/test/jasmine/tests/select_test.js
+++ b/test/jasmine/tests/select_test.js
@@ -2299,7 +2299,7 @@ describe('Test select box and lasso per trace:', function() {
[[150, 150], [300, 300]],
function() {
assertPoints([['NY', 10]]);
- assertRanges([[-83.38, 46.13], [-74.06, 39.29]]);
+ assertRanges([[-83.35, 46.13], [-74.03, 39.29]]);
assertSelectedPoints({0: [0]});
},
null, BOXEVENTS, 'choroplethmap select'
@@ -2315,8 +2315,8 @@ describe('Test select box and lasso per trace:', function() {
assertPoints([['MA', 20]]);
assertSelectedPoints({0: [1]});
assertLassoPoints([
- [-74.06, 43.936], [-74.06, 39.293], [-67.84, 39.293],
- [-67.84, 43.936], [-74.06, 43.936]
+ [-74.03, 43.936], [-74.03, 39.293], [-67.81, 39.293],
+ [-67.81, 43.936], [-74.03, 43.936]
]);
},
null, LASSOEVENTS, 'choroplethmap lasso'
@@ -2656,12 +2656,14 @@ describe('Test select box and lasso per trace:', function() {
assertPoints([
[0, 281, 'Purchases'],
[0, 269, 'Material expenses'],
+ [0, 191, 'Personnel expenses'],
+ [0, 179, 'Other expenses'],
]);
assertSelectedPoints({
- 0: [5, 6]
+ 0: [5, 6, 7, 8]
});
},
- null, [3, 2, 1], 'waterfall lasso'
+ null, [4, 2, 1], 'waterfall lasso'
);
})
.then(function() {
@@ -2705,13 +2707,14 @@ describe('Test select box and lasso per trace:', function() {
assertPoints([
[0, 331.5, 'Author: etpinard'],
[1, 53.5, 'Pull requests'],
+ [1, 15.5, 'Author: etpinard'],
]);
assertSelectedPoints({
0: [2],
- 1: [1]
+ 1: [1, 2]
});
},
- null, [3, 2, 1], 'funnel lasso'
+ null, [4, 2, 1], 'funnel lasso'
);
})
.then(done, done.fail);
@@ -3336,7 +3339,7 @@ describe('Test select box and lasso per trace:', function() {
[[150, 150], [300, 300]],
function() {
assertPoints([['NY', 10]]);
- assertRanges([[-83.38, 46.13], [-74.06, 39.29]]);
+ assertRanges([[-83.35, 46.13], [-74.03, 39.29]]);
assertSelectedPoints({0: [0], 3: []});
},
null, BOXEVENTS, 'choroplethmap select'
@@ -3352,8 +3355,8 @@ describe('Test select box and lasso per trace:', function() {
assertPoints([['MA', 20], []]);
assertSelectedPoints({0: [1], 3: [0]});
assertLassoPoints([
- [-74.06, 43.936], [-74.06, 39.293], [-67.84, 39.293],
- [-67.84, 43.936], [-74.06, 43.936]
+ [-74.03, 43.936], [-74.03, 39.293], [-67.81, 39.293],
+ [-67.81, 43.936], [-74.03, 43.936]
]);
},
null, LASSOEVENTS, 'choroplethmap lasso'