diff --git a/.github/workflows/browser_test.yml b/.github/workflows/browser_test.yml new file mode 100644 index 000000000..330c104d6 --- /dev/null +++ b/.github/workflows/browser_test.yml @@ -0,0 +1,58 @@ +# This workflow will do a clean install, start the selenium server, and run +# all of our browser based tests + +name: Run browser test nightly + +on: + # Trigger the workflow nightly + schedule: + - cron: '0 0 * * *' + +permissions: + contents: read + +jobs: + build: + timeout-minutes: 10 + runs-on: ${{ matrix.os }} + + strategy: + matrix: + # TODO (#2114): re-enable osx build. + # os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest] + node-version: [16.x, 18.x, 20.x] + # See supported Node.js release schedule at + # https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false + + - name: Reconfigure git to use HTTP authentication + run: > + git config --global url."https://github.com/".insteadOf + ssh://git@github.com/ + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Npm Install + run: npm install + + - name: Linux Test Setup + if: runner.os == 'Linux' + run: source ./tests/scripts/setup_linux_env.sh + + - name: MacOS Test Setup + if: runner.os == 'macOS' + run: source ./tests/scripts/setup_osx_env.sh + + - name: Run + run: npm run test:browser + + env: + CI: true diff --git a/package.json b/package.json index d38a8a23d..ba72c1fb9 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "start": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir 'build/src' --declarationDir 'build/declarations'\" \"http-server ./ -s -o /tests/playground.html -c-1\"", "tsc": "gulp tsc", "test": "gulp test", + "test:browser": "npx mocha ./tests/browser/test --config ./tests/browser/test/.mocharc.js", "test:generators": "gulp testGenerators", "test:mocha:interactive": "http-server ./ -o /tests/mocha/index.html -c-1", "test:compile:advanced": "gulp buildAdvancedCompilationTest --debug", diff --git a/tests/browser/.eslintrc.json b/tests/browser/.eslintrc.json new file mode 100644 index 000000000..17590c00c --- /dev/null +++ b/tests/browser/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "env": { + "browser": true, + "mocha": true, + "node": true + }, + "globals": { + "chai": false, + "sinon": false + }, + "rules": { + "no-unused-vars": ["off"], + // Allow uncommented helper functions in tests. + "require-jsdoc": ["off"], + "prefer-rest-params": ["off"], + "no-invalid-this": ["off"] + }, + "extends": "../../.eslintrc.js", + "parserOptions": { + "sourceType": "module" + } +} diff --git a/tests/browser/test/.mocharc.js b/tests/browser/test/.mocharc.js new file mode 100644 index 000000000..42378c7fa --- /dev/null +++ b/tests/browser/test/.mocharc.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = { + ui: 'tdd', + reporter: 'landing', +}; diff --git a/tests/browser/test/basic_block_factory_test.js b/tests/browser/test/basic_block_factory_test.js new file mode 100644 index 000000000..c56834095 --- /dev/null +++ b/tests/browser/test/basic_block_factory_test.js @@ -0,0 +1,72 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Node.js script to run Automated tests in Chrome, via webdriver. + */ + +const webdriverio = require('webdriverio'); +const chai = require('chai'); + +let browser; +suite('Testing Connecting Blocks', function (done) { + // Setting timeout to unlimited as the webdriver takes a longer time to run than most mocha test + this.timeout(0); + + // Setup Selenium for all of the tests + suiteSetup(async function () { + const options = { + capabilities: { + 'browserName': 'chrome', + 'goog:chromeOptions': { + args: ['--allow-file-access-from-files'], + }, + }, + services: [['selenium-standalone']], + logLevel: 'warn', + }; + + // Run in headless mode on Github Actions. + if (process.env.CI) { + options.capabilities['goog:chromeOptions'].args.push( + '--headless', + '--no-sandbox', + '--disable-dev-shm-usage' + ); + } else { + // --disable-gpu is needed to prevent Chrome from hanging on Linux with + // NVIDIA drivers older than v295.20. See + // https://github.com/google/blockly/issues/5345 for details. + options.capabilities['goog:chromeOptions'].args.push('--disable-gpu'); + } + // Use Selenium to bring up the page + const url = + 'https://blockly-demo.appspot.com/static/demos/blockfactory/index.html'; + console.log('Starting webdriverio...'); + browser = await webdriverio.remote(options); + console.log('Loading URL: ' + url); + await browser.url(url); + return browser; + }); + + test('Testing Block Drag', async function () { + const startingBlock = await browser.$( + '#blockly > div > svg.blocklySvg > g > g.blocklyBlockCanvas > g:nth-child(2)' + ); + const blocklyCanvas = await browser.$( + '#blockly > div > svg.blocklySvg > g > g.blocklyBlockCanvas' + ); + const firstPostion = await blocklyCanvas.getAttribute('transform'); + await startingBlock.dragAndDrop({x: 20, y: 20}); + const secondPosition = await blocklyCanvas.getAttribute('transform'); + chai.assert.notEqual(firstPostion, secondPosition); + }); + + // Teardown entire suite after test are done running + suiteTeardown(async function () { + await browser.deleteSession(); + }); +}); diff --git a/tests/browser/test/basic_playground_test.js b/tests/browser/test/basic_playground_test.js new file mode 100644 index 000000000..fa634940b --- /dev/null +++ b/tests/browser/test/basic_playground_test.js @@ -0,0 +1,78 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Node.js script to run Automated tests in Chrome, via webdriver. + */ + +const webdriverio = require('webdriverio'); +const chai = require('chai'); + +let browser; +suite('Testing Connecting Blocks', function (done) { + // Setting timeout to unlimited as the webdriver takes a longer time to run than most mocha test + this.timeout(0); + + // Setup Selenium for all of the tests + suiteSetup(async function () { + const options = { + capabilities: { + 'browserName': 'chrome', + 'goog:chromeOptions': { + args: ['--allow-file-access-from-files'], + }, + }, + services: [['selenium-standalone']], + logLevel: 'warn', + }; + + // Run in headless mode on Github Actions. + if (process.env.CI) { + options.capabilities['goog:chromeOptions'].args.push( + '--headless', + '--no-sandbox', + '--disable-dev-shm-usage' + ); + } else { + // --disable-gpu is needed to prevent Chrome from hanging on Linux with + // NVIDIA drivers older than v295.20. See + // https://github.com/google/blockly/issues/5345 for details. + options.capabilities['goog:chromeOptions'].args.push('--disable-gpu'); + } + // Use Selenium to bring up the page + const url = 'https://blockly-demo.appspot.com/static/tests/playground.html'; + console.log('Starting webdriverio...'); + browser = await webdriverio.remote(options); + console.log('Loading URL: ' + url); + await browser.url(url); + return browser; + }); + + test('Testing Block Flyout', async function () { + const logicButton = await browser.$('#blockly-0'); + logicButton.click(); + const ifDoBlock = await browser.$( + '#blocklyDiv > div > svg:nth-child(7) > g > g.blocklyBlockCanvas > g:nth-child(3)' + ); + await ifDoBlock.dragAndDrop({x: 20, y: 20}); + await new Promise((resolve) => setTimeout(resolve, 2000)); // 2 sec + const blockOnWorkspace = await browser.execute(() => { + const newBlock = Blockly.getMainWorkspace().getAllBlocks(false)[0]; + if (newBlock.id) { + return true; + } else { + return false; + } + }); + + chai.assert.isTrue(blockOnWorkspace); + }); + + // Teardown entire suite after test are done running + suiteTeardown(async function () { + await browser.deleteSession(); + }); +});