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
24 changes: 11 additions & 13 deletions web-console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ This is the unified Druid web console that servers as a data management layer fo

## How to watch and run for development

1. You need to be withing the `web-console` directory
1. You need to be within the `web-console` directory
2. Install the modules with `npm install`
3. Run `npm start` will start in development mode and will proxy druid requests to `localhost:8888`

Expand Down Expand Up @@ -82,26 +82,24 @@ From the web-console directory:
3. Run end-to-end tests: `npm run test-e2e`
4. Stop druid cluster: `script/druid stop`

If you already have a druid cluster running on the standard ports, the steps to build/start/stop a druid cluster can
be skipped.

### Debugging

#### Screenshots

`e2e-tests/util/debug.ts:saveScreenshotIfError()` is used to save a screenshot of the web console
when the test fails. For example, if `e2e-tests/tutotrial-batch.spec.ts` fails, it will create
when the test fails. For example, if `e2e-tests/tutorial-batch.spec.ts` fails, it will create
`load-data-from-local-disk-error-screenshot.png`.

#### Disabling Headless Mode

Disabling headless mode while running the tests can be helpful. One way of doing this is by using
`e2e-tests/util/playwright:createBrowserDebug()`. For example, the test can be modified to change

```
import { createBrowserNormal as createBrowser } from './util/playwright'
```
Disabling headless mode while running the tests can be helpful. This can be done via the `DRUID_E2E_TEST_HEADLESS`
environment variable, which defaults to `true`.

to

```
import { createBrowserDebug as createBrowser } from './util/playwright'`
```
#### Running Against Alternate Web Console

The environment variable `DRUID_E2E_TEST_UNIFIED_CONSOLE_PORT` can be used to target a web console running on a
non-default port (i.e., not port `8888`). For example, this environment variable can be used to target the
development mode of the web console (started via `npm start`), which runs on port `18081`.
4 changes: 2 additions & 2 deletions web-console/e2e-tests/auto-compaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import axios from 'axios';
import path from 'path';
import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { CompactionConfig } from './component/datasources/compaction';
import { Datasource } from './component/datasources/datasource';
Expand All @@ -29,7 +29,7 @@ import { COORDINATOR_URL } from './util/druid';
import { DRUID_EXAMPLES_QUICKSTART_TUTORIAL_DIR } from './util/druid';
import { UNIFIED_CONSOLE_URL } from './util/druid';
import { runIndexTask } from './util/druid';
import { createBrowserNormal as createBrowser } from './util/playwright';
import { createBrowser } from './util/playwright';
import { createPage } from './util/playwright';
import { retryIfJestAssertionError } from './util/retry';
import { waitTillWebConsoleReady } from './util/setup';
Expand Down
6 changes: 3 additions & 3 deletions web-console/e2e-tests/component/datasources/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { clickButton } from '../../util/playwright';
import { getLabeledInput } from '../../util/playwright';
Expand Down Expand Up @@ -61,7 +61,7 @@ export class DatasourcesOverview {

async getDatasources(): Promise<Datasource[]> {
await this.page.goto(this.baseUrl);
await this.page.reload({ waitUntil: 'networkidle0' });
await this.page.reload({ waitUntil: 'networkidle' });

const data = await extractTable(this.page, 'div div.rt-tr-group', 'div.rt-td');

Expand Down Expand Up @@ -116,6 +116,6 @@ export class DatasourcesOverview {

const editActions = await this.page.$$('span[icon=wrench]');
editActions[index].click();
await this.page.waitFor('ul.bp3-menu');
await this.page.waitForSelector('ul.bp3-menu');
}
}
4 changes: 2 additions & 2 deletions web-console/e2e-tests/component/ingestion/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { extractTable } from '../../util/table';

Expand Down Expand Up @@ -50,7 +50,7 @@ export class IngestionOverview {

async getTasks(): Promise<IngestionTask[]> {
await this.page.goto(this.baseUrl);
await this.page.reload({ waitUntil: 'networkidle0' });
await this.page.reload({ waitUntil: 'networkidle' });

const data = await extractTable(this.page, 'div.bottom-pane div.rt-tr-group', 'div.rt-td');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { selectSuggestibleInput } from '../../../util/playwright';
import { getLabeledInput } from '../../../util/playwright';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { clickButton } from '../../../util/playwright';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { setLabeledInput } from '../../../util/playwright';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { setLabeledInput } from '../../../util/playwright';

Expand Down
36 changes: 19 additions & 17 deletions web-console/e2e-tests/component/load-data/data-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { clickButton } from '../../util/playwright';
import { clickLabeledButton } from '../../util/playwright';
Expand Down Expand Up @@ -60,7 +60,8 @@ export class DataLoader {
}

private async start() {
await this.page.click(`"${this.connector.name}"`);
const cardSelector = `//*[contains(@class,"bp3-card")][p[contains(text(),"${this.connector.name}")]]`;
await this.page.click(cardSelector);
await clickButton(this.page, 'Connect data');
}

Expand All @@ -73,53 +74,54 @@ export class DataLoader {

private async validateConnect(validator: (preview: string) => void) {
const previewSelector = '.raw-lines';
await this.page.waitFor(previewSelector);
await this.page.waitForSelector(previewSelector);
const preview = await this.page.$eval(previewSelector, el => (el as HTMLTextAreaElement).value);
validator(preview!);
}

private async parseData() {
await this.page.waitFor('.parse-data-table');
await this.page.waitForSelector('.parse-data-table');
await clickButton(this.page, 'Next: Parse time');
}

private async parseTime() {
await this.page.waitFor('.parse-time-table');
await this.page.waitForSelector('.parse-time-table');
await clickButton(this.page, 'Next: Transform');
}

private async transform() {
await this.page.waitFor('.transform-table');
await this.page.waitForSelector('.transform-table');
await clickButton(this.page, 'Next: Filter');
}

private async filter() {
await this.page.waitFor('.filter-table');
await this.page.waitForSelector('.filter-table');
await clickButton(this.page, 'Next: Configure schema');
}

private async configureSchema(configureSchemaConfig: ConfigureSchemaConfig) {
await this.page.waitFor('.schema-table');
await this.page.waitForSelector('.schema-table');
await this.applyConfigureSchemaConfig(configureSchemaConfig);
await clickButton(this.page, 'Next: Partition');
}

private async applyConfigureSchemaConfig(configureSchemaConfig: ConfigureSchemaConfig) {
const rollup = await this.page.$('//*[text()="Rollup"]/input');
const rollupChecked = await rollup!.evaluate(el => (el as HTMLInputElement).checked);
const rollupSelector = '//*[text()="Rollup"]';
const rollupInput = await this.page.$(`${rollupSelector}/input`);
const rollupChecked = await rollupInput!.evaluate(el => (el as HTMLInputElement).checked);
if (rollupChecked !== configureSchemaConfig.rollup) {
await rollup!.click();
await this.page.click(rollupSelector);
const confirmationDialogSelector = '//*[contains(@class,"bp3-alert-body")]';
await this.page.waitFor(confirmationDialogSelector);
await this.page.waitForSelector(confirmationDialogSelector);
await clickButton(this.page, 'Yes');
const statusMessageSelector = '.recipe-toaster';
await this.page.waitFor(statusMessageSelector);
await this.page.waitForSelector(statusMessageSelector);
await this.page.click(`${statusMessageSelector} button`);
}
}

private async partition(partitionConfig: PartitionConfig) {
await this.page.waitFor('div.load-data-view.partition');
await this.page.waitForSelector('div.load-data-view.partition');
await this.applyPartitionConfig(partitionConfig);
await clickButton(this.page, 'Next: Tune');
}
Expand All @@ -140,12 +142,12 @@ export class DataLoader {
}

private async tune() {
await this.page.waitFor('div.load-data-view.tuning');
await this.page.waitForSelector('div.load-data-view.tuning');
await clickButton(this.page, 'Next: Publish');
}

private async publish(publishConfig: PublishConfig) {
await this.page.waitFor('div.load-data-view.publish');
await this.page.waitForSelector('div.load-data-view.publish');
await this.applyPublishConfig(publishConfig);
await clickButton(this.page, 'Edit spec');
}
Expand All @@ -157,7 +159,7 @@ export class DataLoader {
}

private async editSpec() {
await this.page.waitFor('div.load-data-view.spec');
await this.page.waitForSelector('div.load-data-view.spec');
await clickButton(this.page, 'Submit');
}
}
Expand Down
6 changes: 3 additions & 3 deletions web-console/e2e-tests/component/query/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { clickButton } from '../../util/playwright';
import { setInput } from '../../util/playwright';
Expand All @@ -36,12 +36,12 @@ export class QueryOverview {

async runQuery(query: string): Promise<string[][]> {
await this.page.goto(this.baseUrl);
await this.page.reload({ waitUntil: 'networkidle0' });
await this.page.reload({ waitUntil: 'networkidle' });

const input = await this.page.$('div.query-input textarea');
await setInput(input!, query);
await clickButton(this.page, 'Run');
await this.page.waitFor('div.query-info');
await this.page.waitForSelector('div.query-info');

return await extractTable(this.page, 'div.query-output div.rt-tr-group', 'div.rt-td');
}
Expand Down
4 changes: 2 additions & 2 deletions web-console/e2e-tests/reindexing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import path from 'path';
import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { DatasourcesOverview } from './component/datasources/overview';
import { IngestionOverview } from './component/ingestion/overview';
Expand All @@ -32,7 +32,7 @@ import { saveScreenshotIfError } from './util/debug';
import { DRUID_EXAMPLES_QUICKSTART_TUTORIAL_DIR } from './util/druid';
import { UNIFIED_CONSOLE_URL } from './util/druid';
import { runIndexTask } from './util/druid';
import { createBrowserNormal as createBrowser } from './util/playwright';
import { createBrowser } from './util/playwright';
import { createPage } from './util/playwright';
import { retryIfJestAssertionError } from './util/retry';
import { waitTillWebConsoleReady } from './util/setup';
Expand Down
7 changes: 4 additions & 3 deletions web-console/e2e-tests/tutorial-batch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

import { DatasourcesOverview } from './component/datasources/overview';
import { IngestionOverview } from './component/ingestion/overview';
Expand All @@ -28,8 +28,9 @@ import { LocalFileDataConnector } from './component/load-data/data-connector/loc
import { DataLoader } from './component/load-data/data-loader';
import { QueryOverview } from './component/query/overview';
import { saveScreenshotIfError } from './util/debug';
import { DRUID_EXAMPLES_QUICKSTART_TUTORIAL_DIR } from './util/druid';
import { UNIFIED_CONSOLE_URL } from './util/druid';
import { createBrowserNormal as createBrowser } from './util/playwright';
import { createBrowser } from './util/playwright';
import { createPage } from './util/playwright';
import { retryIfJestAssertionError } from './util/retry';
import { waitTillWebConsoleReady } from './util/setup';
Expand Down Expand Up @@ -57,7 +58,7 @@ describe('Tutorial: Loading a file', () => {
const testName = 'load-data-from-local-disk-';
const datasourceName = testName + new Date().toISOString();
const dataConnector = new LocalFileDataConnector(page, {
baseDirectory: 'quickstart/tutorial/',
baseDirectory: DRUID_EXAMPLES_QUICKSTART_TUTORIAL_DIR,
fileFilter: 'wikiticker-2015-09-12-sampled.json.gz',
});
const configureSchemaConfig = new ConfigureSchemaConfig({ rollup: false });
Expand Down
2 changes: 1 addition & 1 deletion web-console/e2e-tests/util/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

export async function saveScreenshotIfError(
filenamePrefix: string,
Expand Down
3 changes: 2 additions & 1 deletion web-console/e2e-tests/util/druid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import { execSync } from 'child_process';
import path from 'path';

export const UNIFIED_CONSOLE_URL = 'http://localhost:8888/unified-console.html';
const UNIFIED_CONSOLE_PORT = process.env['DRUID_E2E_TEST_UNIFIED_CONSOLE_PORT'] || '8888';
export const UNIFIED_CONSOLE_URL = `http://localhost:${UNIFIED_CONSOLE_PORT}/unified-console.html`;
export const COORDINATOR_URL = 'http://localhost:8081';

const UTIL_DIR = __dirname;
Expand Down
16 changes: 5 additions & 11 deletions web-console/e2e-tests/util/playwright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,16 @@
* limitations under the License.
*/

import * as playwright from 'playwright-core';
import * as playwright from 'playwright-chromium';

const DEBUG = true;
const TRUE = 'true';
const WIDTH = 1920;
const HEIGHT = 1080;
const PADDING = 128;

export async function createBrowserNormal(): Promise<playwright.Browser> {
return createBrowserInternal(!DEBUG);
}

export async function createBrowserDebug(): Promise<playwright.Browser> {
return createBrowserInternal(DEBUG);
}

async function createBrowserInternal(debug: boolean): Promise<playwright.Browser> {
export async function createBrowser(): Promise<playwright.Browser> {
const headless = process.env['DRUID_E2E_TEST_HEADLESS'] || TRUE;
const debug = headless !== TRUE;
const launchOptions: any = {
args: [`--window-size=${WIDTH},${HEIGHT + PADDING}`],
};
Expand Down
6 changes: 3 additions & 3 deletions web-console/e2e-tests/util/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import { UNIFIED_CONSOLE_URL } from './druid';
import { createBrowserNormal as createBrowser } from './playwright';
import { createBrowser } from './playwright';
import { createPage } from './playwright';

export async function waitTillWebConsoleReady() {
Expand All @@ -26,8 +26,8 @@ export async function waitTillWebConsoleReady() {
try {
const page = await createPage(browser);
await page.goto(UNIFIED_CONSOLE_URL);
await page.waitFor('//*[contains(text(),"console will not function at the moment")]', {
visibility: 'hidden',
await page.waitForSelector('//*[contains(text(),"console will not function at the moment")]', {
state: 'hidden',
});
} finally {
await browser.close();
Expand Down
Loading