test: trigger only flow should not be publishable
This commit is contained in:
1
.github/workflows/playwright.yml
vendored
1
.github/workflows/playwright.yml
vendored
@@ -23,6 +23,7 @@ env:
|
|||||||
REDIS_HOST: localhost
|
REDIS_HOST: localhost
|
||||||
APP_ENV: production
|
APP_ENV: production
|
||||||
LICENSE_KEY: dummy_license_key
|
LICENSE_KEY: dummy_license_key
|
||||||
|
BACKEND_APP_URL: http://localhost:3000
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
11
packages/e2e-tests/fixtures/bullmq-helper.js
Normal file
11
packages/e2e-tests/fixtures/bullmq-helper.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
const { expect } = require('../fixtures/index');
|
||||||
|
|
||||||
|
export const expectNoDelayedJobForFlow = async (flowId, request) => {
|
||||||
|
const token = btoa(`${process.env.BULLMQ_DASHBOARD_USERNAME}:${process.env.BULLMQ_DASHBOARD_PASSWORD}`);
|
||||||
|
const queues = await request.get(`${process.env.BACKEND_APP_URL}/admin/queues/api/queues?activeQueue=flow&status=delayed&page=1`, {
|
||||||
|
headers: {'Authorization': `Basic ${token}`}
|
||||||
|
});
|
||||||
|
const queuesJsonResponse = await queues.json();
|
||||||
|
const flowQueue = queuesJsonResponse.queues.find(queue => queue.name === "flow");
|
||||||
|
await expect(flowQueue.jobs.find(job => job.name === `flow-${flowId}`)).toBeUndefined();
|
||||||
|
};
|
@@ -24,6 +24,7 @@ export class FlowEditorPage extends AuthenticatedPage {
|
|||||||
this.unpublishFlowButton = this.page.getByTestId('unpublish-flow-button');
|
this.unpublishFlowButton = this.page.getByTestId('unpublish-flow-button');
|
||||||
this.publishFlowButton = this.page.getByTestId('publish-flow-button');
|
this.publishFlowButton = this.page.getByTestId('publish-flow-button');
|
||||||
this.infoSnackbar = this.page.getByTestId('flow-cannot-edit-info-snackbar');
|
this.infoSnackbar = this.page.getByTestId('flow-cannot-edit-info-snackbar');
|
||||||
|
this.errorSnackbar = this.page.getByTestId('snackbar-error');
|
||||||
this.trigger = this.page.getByLabel('Trigger on weekends?');
|
this.trigger = this.page.getByLabel('Trigger on weekends?');
|
||||||
this.stepCircularLoader = this.page.getByTestId('step-circular-loader');
|
this.stepCircularLoader = this.page.getByTestId('step-circular-loader');
|
||||||
this.flowName = this.page.getByTestId('editableTypography');
|
this.flowName = this.page.getByTestId('editableTypography');
|
||||||
@@ -32,16 +33,12 @@ export class FlowEditorPage extends AuthenticatedPage {
|
|||||||
.locator('input');
|
.locator('input');
|
||||||
|
|
||||||
this.flowStep = this.page.getByTestId('flow-step');
|
this.flowStep = this.page.getByTestId('flow-step');
|
||||||
|
this.rssFeedUrl = this.page.getByTestId('parameters.feedUrl-text');
|
||||||
}
|
}
|
||||||
|
|
||||||
async createWebhookTrigger(workSynchronously) {
|
async createWebhookTrigger(workSynchronously) {
|
||||||
await this.appAutocomplete.click();
|
this.chooseAppAndTrigger('Webhook', 'Catch raw webhook');
|
||||||
await this.page.getByRole('option', { name: 'Webhook' }).click();
|
|
||||||
|
|
||||||
await expect(this.eventAutocomplete).toBeVisible();
|
|
||||||
await this.eventAutocomplete.click();
|
|
||||||
await this.page.getByRole('option', { name: 'Catch raw webhook' }).click();
|
|
||||||
await this.continueButton.click();
|
|
||||||
await this.page
|
await this.page
|
||||||
.getByTestId('parameters.workSynchronously-autocomplete')
|
.getByTestId('parameters.workSynchronously-autocomplete')
|
||||||
.click();
|
.click();
|
||||||
@@ -69,6 +66,19 @@ export class FlowEditorPage extends AuthenticatedPage {
|
|||||||
return await webhookUrl.inputValue();
|
return await webhookUrl.inputValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async chooseAppAndTrigger(appName, triggerEvent) {
|
||||||
|
await expect(this.appAutocomplete).toHaveCount(1);
|
||||||
|
await this.appAutocomplete.click();
|
||||||
|
await this.page.getByRole('option', { name: appName }).click();
|
||||||
|
await expect(this.eventAutocomplete).toBeVisible();
|
||||||
|
await this.eventAutocomplete.click();
|
||||||
|
await Promise.all([
|
||||||
|
this.page.waitForResponse(resp => /(apps\/.*\/triggers\/.*\/substeps)/.test(resp.url()) && resp.status() === 200),
|
||||||
|
this.page.getByRole('option', { name: triggerEvent }).click(),
|
||||||
|
]);
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
async chooseAppAndEvent(appName, eventName) {
|
async chooseAppAndEvent(appName, eventName) {
|
||||||
await expect(this.appAutocomplete).toHaveCount(1);
|
await expect(this.appAutocomplete).toHaveCount(1);
|
||||||
await this.appAutocomplete.click();
|
await this.appAutocomplete.click();
|
||||||
@@ -88,4 +98,10 @@ export class FlowEditorPage extends AuthenticatedPage {
|
|||||||
await expect(this.testOutput).toBeVisible();
|
await expect(this.testOutput).toBeVisible();
|
||||||
await this.continueButton.click();
|
await this.continueButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async dismissErrorSnackbar() {
|
||||||
|
await expect(this.errorSnackbar).toBeVisible();
|
||||||
|
await this.errorSnackbar.click();
|
||||||
|
await expect(this.errorSnackbar).toHaveCount(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
18
packages/e2e-tests/fixtures/postgres/postgres-helper.js
Normal file
18
packages/e2e-tests/fixtures/postgres/postgres-helper.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const { pgPool } = require('./postgres-config');
|
||||||
|
const { expect } = require('../../fixtures/index');
|
||||||
|
|
||||||
|
export const flowShouldNotHavePublishedAtDateFilled = async (flowId) => {
|
||||||
|
const queryFlow = {
|
||||||
|
text: 'SELECT * FROM flows WHERE id = $1',
|
||||||
|
values: [flowId]
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const queryFlowResult = await pgPool.query(queryFlow);
|
||||||
|
expect(queryFlowResult.rowCount).toEqual(1);
|
||||||
|
expect(queryFlowResult.rows[0].published_at).toBeNull();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
@@ -1,5 +1,5 @@
|
|||||||
const { test, expect } = require('../../fixtures/index');
|
const { test, expect } = require('../../fixtures/index');
|
||||||
const { pgPool } = require('../../fixtures/postgres-config');
|
const { pgPool } = require('../../fixtures/postgres/postgres-config');
|
||||||
|
|
||||||
test.describe('Admin Applications', () => {
|
test.describe('Admin Applications', () => {
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
|
53
packages/e2e-tests/tests/flow-editor/flow-validation.spec.js
Normal file
53
packages/e2e-tests/tests/flow-editor/flow-validation.spec.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
const { test, expect } = require('../../fixtures/index');
|
||||||
|
const { expectNoDelayedJobForFlow } = require('../../fixtures/bullmq-helper');
|
||||||
|
const { flowShouldNotHavePublishedAtDateFilled } = require('../../fixtures/postgres/postgres-helper');
|
||||||
|
|
||||||
|
test.describe('Flow Validation', () => {
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
await page.getByTestId('create-flow-button').click();
|
||||||
|
await page.waitForURL(
|
||||||
|
/\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/
|
||||||
|
);
|
||||||
|
await expect(page.getByTestId('flow-step')).toHaveCount(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should not be able to publish flow without trigger', async ({
|
||||||
|
flowEditorPage,
|
||||||
|
page,
|
||||||
|
request
|
||||||
|
}) => {
|
||||||
|
const flowId = await page.url().split('editor/').pop();
|
||||||
|
|
||||||
|
await flowEditorPage.flowName.click();
|
||||||
|
await flowEditorPage.flowNameInput.fill('incompleteFlow');
|
||||||
|
await flowEditorPage.chooseAppAndTrigger('RSS', 'New items in feed');
|
||||||
|
|
||||||
|
await flowEditorPage.publishFlowButton.click();
|
||||||
|
await flowEditorPage.dismissErrorSnackbar();
|
||||||
|
|
||||||
|
await flowShouldNotHavePublishedAtDateFilled(flowId);
|
||||||
|
await expectNoDelayedJobForFlow(flowId, request);
|
||||||
|
|
||||||
|
await flowEditorPage.rssFeedUrl.fill('http://rss.cnn.com/rss/money_mostpopular.rss');
|
||||||
|
await expect(flowEditorPage.continueButton).toHaveCount(1);
|
||||||
|
await flowEditorPage.continueButton.click();
|
||||||
|
|
||||||
|
await flowEditorPage.publishFlowButton.click();
|
||||||
|
await flowEditorPage.dismissErrorSnackbar();
|
||||||
|
|
||||||
|
await flowShouldNotHavePublishedAtDateFilled(flowId);
|
||||||
|
await expectNoDelayedJobForFlow(flowId, request);
|
||||||
|
|
||||||
|
await expect(flowEditorPage.testOutput).not.toBeVisible();
|
||||||
|
await flowEditorPage.testAndContinueButton.click();
|
||||||
|
await expect(flowEditorPage.testOutput).toBeVisible();
|
||||||
|
await expect(flowEditorPage.hasNoOutput).not.toBeVisible();
|
||||||
|
await flowEditorPage.continueButton.click();
|
||||||
|
|
||||||
|
await flowEditorPage.publishFlowButton.click();
|
||||||
|
await expect(page.getByTestId('snackbar-error')).toBeVisible();
|
||||||
|
|
||||||
|
await flowShouldNotHavePublishedAtDateFilled(flowId);
|
||||||
|
await expectNoDelayedJobForFlow(flowId, request);
|
||||||
|
});
|
||||||
|
});
|
@@ -1,5 +1,5 @@
|
|||||||
const { publicTest, expect } = require('../../fixtures/index');
|
const { publicTest, expect } = require('../../fixtures/index');
|
||||||
const { pgPool } = require('../../fixtures/postgres-config');
|
const { pgPool } = require('../../fixtures/postgres/postgres-config');
|
||||||
const { DateTime } = require('luxon');
|
const { DateTime } = require('luxon');
|
||||||
|
|
||||||
publicTest.describe('Accept invitation page', () => {
|
publicTest.describe('Accept invitation page', () => {
|
||||||
|
Reference in New Issue
Block a user