Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ jobs:
- name: Npm Clean Install
run: npm ci

- name: Setup Chrome
if: runner.os == 'Linux'
uses: browser-actions/setup-chrome@v1

- name: Linux Test Setup
if: runner.os == 'Linux'
run: source ./tests/scripts/setup_linux_env.sh
Expand Down
5 changes: 4 additions & 1 deletion packages/blockly/core/workspace_audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ export class WorkspaceAudio {
source.start();
} else if (this.parentWorkspace) {
// Maybe a workspace on a lower level knows about this sound.
this.parentWorkspace.getAudioManager().play(name, opt_volume);
const parentAudio = this.parentWorkspace.getAudioManager();
if (parentAudio !== this) {
parentAudio.play(name, opt_volume);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/blockly/core/zoom_controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
// Unused import preserved for side-effects. Remove if unneeded.
import './events/events_click.js';

import {IFocusableNode} from './blockly.js';
import * as browserEvents from './browser_events.js';
import {ComponentManager} from './component_manager.js';
import * as Css from './css.js';
import {EventType} from './events/type.js';
import * as eventUtils from './events/utils.js';
import {IFocusableNode} from './interfaces/i_focusable_node.js';
import type {IPositionable} from './interfaces/i_positionable.js';
import type {UiMetrics} from './metrics_manager.js';
import {Msg} from './msg.js';
Expand Down
1 change: 1 addition & 0 deletions packages/blockly/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export default [
'tests/mocha/.mocharc.js',
'tests/migration/validate-renamings.mjs',
'tests/scripts/magic_symlink.js',
'tests/scripts/webdriver_helpers.js',
],
languageOptions: {
globals: {
Expand Down
61 changes: 42 additions & 19 deletions packages/blockly/scripts/gulpfiles/test_tasks.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ import * as gulp from 'gulp';
import gzip from 'gulp-gzip';
import * as fs from 'fs';
import * as path from 'path';
import {execSync} from 'child_process';
import {spawnSync} from 'child_process';
import {rimraf} from 'rimraf';

import {RELEASE_DIR, TEST_TSC_OUTPUT_DIR} from './config.mjs';

import {runMochaTestsInBrowser} from '../../tests/mocha/webdriver.js';
import {runGeneratorsInBrowser} from '../../tests/generators/webdriver.js';
import {runCompileCheckInBrowser} from '../../tests/compile/webdriver.js';

const OUTPUT_DIR = 'build/generators';
const GOLDEN_DIR = 'tests/generators/golden';
Expand Down Expand Up @@ -121,8 +119,20 @@ function reportTestResult() {
* @return {Promise} Asynchronous result.
*/
async function runTestCommand(id, command) {
return runTestTask(id, async() => {
return execSync(command, {stdio: 'inherit'});
return runTestTask(id, async () => {
const result = spawnSync(command, {
shell: true,
stdio: 'inherit',
env: process.env,
});
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
throw new Error(
`Command failed with exit code ${result.status}: ${command}`,
);
}
});
}

Expand Down Expand Up @@ -257,24 +267,25 @@ async function metadata() {
* Run Mocha tests inside a browser.
* @return {Promise} Asynchronous result.
*/
async function mocha(exitOnCompletion = true) {
return runTestTask('mocha', async () => {
const result = await runMochaTestsInBrowser(exitOnCompletion).catch(e => {
throw e;
});
if (result) {
throw new Error('Mocha tests failed');
}
console.log('Mocha tests passed');
});
function mocha() {
// Run in a subprocess so webdriverio is not loaded inside gulp's asyncDone
// domain (which has been observed to exit the process on CI after ~2s).
return runTestCommand('mocha', 'node tests/mocha/webdriver.js');
}

/**
* Run Mocha tests inside a browser and keep the browser open upon completion.
* @return {Promise} Asynchronous result.
*/
export async function interactiveMocha() {
return mocha(false);
export function interactiveMocha() {
return runTestTask('interactiveMocha', () => {
return runMochaTestsInBrowser(false).then((result) => {
if (result) {
throw new Error('Mocha tests failed');
}
console.log('Mocha tests passed');
});
});
}

/**
Expand Down Expand Up @@ -335,7 +346,16 @@ export async function generators() {
rimraf.sync(OUTPUT_DIR);
fs.mkdirSync(OUTPUT_DIR);

await runGeneratorsInBrowser(OUTPUT_DIR);
const result = spawnSync('node', ['tests/generators/webdriver.js', OUTPUT_DIR], {
stdio: 'inherit',
env: process.env,
});
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
throw new Error('Generator browser tests failed.');
}

const generatorSuffixes = ['js', 'py', 'dart', 'lua', 'php'];
let failed = 0;
Expand Down Expand Up @@ -375,7 +395,10 @@ function advancedCompile() {
* @return {Promise} Asynchronous result.
*/
function advancedCompileInBrowser() {
return runTestTask('advanced_compile_in_browser', runCompileCheckInBrowser);
return runTestCommand(
'advanced_compile_in_browser',
'node tests/compile/webdriver.js',
);
}

/**
Expand Down
73 changes: 22 additions & 51 deletions packages/blockly/tests/compile/webdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,78 +9,49 @@
* Chrome, via webdriver.
*/
const webdriverio = require('webdriverio');

const {
getWebdriverOptions,
runBrowserTestMain,
} = require('../scripts/webdriver_helpers.js');

/**
* Run the generator for a given language and save the results to a file.
* Run the health check in the browser.
* @param {Thenable} browser A Thenable managing the processing of the browser
* tests.
*/
async function runHealthCheckInBrowser(browser) {
const result = await browser.execute(() => {
return healthCheck();
})
if (!result) throw Error('Health check failed in advanced compilation test.');
return healthCheck();
});
if (!result) {
throw Error('Health check failed in advanced compilation test.');
}
console.log('Health check completed successfully.');
}

/**
* Runs the generator tests in Chrome. It uses webdriverio to
* launch Chrome and load index.html. Outputs a summary of the test results
* to the console and outputs files for later validation.
* @return the Thenable managing the processing of the browser tests.
* Runs the compile health check in Chrome.
* @return {number} 0 on success.
*/
async function runCompileCheckInBrowser() {
const options = {
capabilities: {
browserName: 'chrome',
},
logLevel: 'warn',
};
// Run in headless mode on Github Actions.
if (process.env.CI) {
options.capabilities['goog:chromeOptions'] = {
args: [
'--headless',
'--no-sandbox',
'--disable-dev-shm-usage',
'--allow-file-access-from-files',
]
};
} 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: ['--allow-file-access-from-files', '--disable-gpu']
};
}
const options = getWebdriverOptions();

const url = 'file://' + __dirname + '/index.html';

console.log('Starting webdriverio...');
const browser = await webdriverio.remote(options);
console.log('Loading url: ' + url);
await browser.url(url);

await runHealthCheckInBrowser(browser);

await browser.deleteSession();
try {
console.log('Loading url: ' + url);
await browser.url(url);
await runHealthCheckInBrowser(browser);
} finally {
await browser.deleteSession();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
return 0;
}

if (require.main === module) {
runCompileCheckInBrowser().catch(e => {
console.error(e);
process.exit(1);
}).then(function(result) {
if (result) {
console.log('Compile test failed');
process.exit(1);
} else {
console.log('Compile test passed');
process.exit(0);
}
});
runBrowserTestMain(() => runCompileCheckInBrowser());
}

module.exports = {runCompileCheckInBrowser};
Loading
Loading