Skip to content
Snippets Groups Projects
Commit b9322395 authored by Tom Robinson's avatar Tom Robinson
Browse files

Merge branch 'master' of github.com:metabase/metabase into issue-4720

parents a5c4a0a8 66a042c6
No related branches found
No related tags found
No related merge requests found
......@@ -106,14 +106,25 @@ $ yarn run build-watch
Run unit tests with
yarn run jest # Jest
yarn run test # Karma
yarn run test-e2e # Selenium Webdriver
Run the linters and type checker with
yarn run lint
yarn run flow
#### End-to-end tests
End-to-end tests are written with [webschauffeur](https://github.com/metabase/webchauffeur) which is a wrapper around [`selenium-webdriver`](https://www.npmjs.com/package/selenium-webdriver).
Run E2E tests once with
yarn run test-e2e
or use a persistent browser session with
yarn run test-e2e-dev
## Backend development
Leiningen and your REPL are the main development tools for the backend. There are some directions below on how to setup your REPL for easier development.
......
......@@ -143,8 +143,7 @@ export default class Navbar extends Component {
</li>
<li className="pl3 hide sm-show">
<Link to={Urls.question()} data-metabase-event={"Navbar;New Question"} style={this.styles.newQuestion} className="NavNewQuestion rounded inline-block bg-white text-brand text-bold cursor-pointer px2 no-decoration transition-all">
New
<span>Question</span>
New <span>Question</span>
</Link>
</li>
<li className="flex-align-right transition-background">
......
......@@ -176,8 +176,10 @@ export default class EntityList extends Component {
const section = this.getSection();
const hasEntitiesInPlainState = entityIds.length > 0 || section.section !== "all";
const showActionHeader = (editable && selectedCount > 0);
const showSearchHeader = (entityIds.length > 0 && showSearchWidget);
const showSearchHeader = (hasEntitiesInPlainState && showSearchWidget);
const showEntityFilterWidget = onChangeSection;
return (
<div style={style}>
......@@ -201,7 +203,7 @@ export default class EntityList extends Component {
:
null
}
{ showEntityFilterWidget && entityIds.length > 0 &&
{ showEntityFilterWidget && hasEntitiesInPlainState &&
<EntityFilterWidget
section={section}
onChange={onChangeSection}
......
#!/usr/bin/env node
const exec = require('child_process').exec
const execSync = require('child_process').execSync
const fs = require('fs');
const webdriver = require('selenium-webdriver');
// User input initialization
const stdin = fs.openSync('/dev/stdin', 'rs');
const buffer = Buffer.alloc(8);
// Yarn must be executed from project root
process.chdir(__dirname + '/../..');
const url = 'http://localhost:9515';
const driverProcess = exec('chromedriver --port=9515');
const driver = new webdriver.Builder()
.forBrowser('chrome')
.usingServer(url)
.build();
driver.getSession().then(function (session) {
const id = session.getId()
console.log('Launched persistent Webdriver session with session ID ' + id, url);
function executeTest() {
const hasCommandToExecuteBeforeReload =
process.argv.length >= 4 && process.argv[2] === '--exec-before'
if (hasCommandToExecuteBeforeReload) {
console.log(execSync(process.argv[3]).toString())
}
const cmd = 'WEBDRIVER_SESSION_ID=' + id + ' WEBDRIVER_SESSION_URL=' + url + ' yarn run test-e2e';
console.log(cmd);
const testProcess = exec(cmd);
testProcess.stdout.pipe(process.stdout);
testProcess.stderr.pipe(process.stderr);
testProcess.on('exit', function () {
console.log("Press <Enter> to rerun tests or <C-c> to quit.")
fs.readSync(stdin, buffer, 0, 8);
executeTest();
})
}
executeTest();
});
process.on('SIGTERM', function () {
console.log('Shutting down...')
driver.quit().then(function () {
process.exit(0)
});
driverProcess.kill('SIGINT');
});
import { Builder } from "selenium-webdriver";
import { Builder, WebDriver } from "selenium-webdriver";
import { USE_SAUCE, sauceCapabilities, sauceServer } from './sauce';
import createSharedResource from "./shared-resource";
const SESSION_URL = process.env["WEBDRIVER_SESSION_URL"];
const SESSION_ID = process.env["WEBDRIVER_SESSION_ID"];
const USE_EXISTING_SESSION = SESSION_URL && SESSION_ID;
export const getConfig = ({ name }) => {
if (USE_SAUCE) {
return {
......@@ -35,24 +39,36 @@ export const WebdriverResource = createSharedResource("WebdriverResource", {
},
async start(webdriver) {
if (!webdriver.driver) {
let builder = new Builder();
if (webdriver.config.capabilities) {
builder.withCapabilities(webdriver.config.capabilities);
}
if (webdriver.config.server) {
builder.usingServer(webdriver.config.server);
}
if (webdriver.config.browser) {
builder.forBrowser(webdriver.config.browser);
if (USE_EXISTING_SESSION) {
const _http = require('selenium-webdriver/http');
const client = new _http.HttpClient(SESSION_URL, null, null);
const executor = new _http.Executor(client);
webdriver.driver = await WebDriver.attachToSession(executor, SESSION_ID);
} else {
let builder = new Builder();
if (webdriver.config.capabilities) {
builder.withCapabilities(webdriver.config.capabilities);
}
if (webdriver.config.server) {
builder.usingServer(webdriver.config.server);
}
if (webdriver.config.browser) {
builder.forBrowser(webdriver.config.browser);
}
webdriver.driver = builder.build();
}
webdriver.driver = builder.build();
}
},
async stop(webdriver) {
if (webdriver.driver) {
const driver = webdriver.driver;
delete webdriver.driver;
await driver.quit();
if (!USE_EXISTING_SESSION) {
await driver.quit();
}
}
}
});
......@@ -151,6 +151,7 @@
"test": "karma start frontend/test/karma.conf.js --single-run",
"test-watch": "karma start frontend/test/karma.conf.js --auto-watch --reporters nyan",
"test-e2e": "JASMINE_CONFIG_PATH=./frontend/test/e2e/support/jasmine.json jasmine",
"test-e2e-dev": "./frontend/test/e2e-with-persistent-browser.js",
"test-e2e-sauce": "USE_SAUCE=true yarn run test-e2e",
"build": "webpack --bail",
"build-watch": "webpack --watch",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment