Skip to content

Commit

Permalink
6261/delete alert tests (keystonejs#6382)
Browse files Browse the repository at this point in the history
* new deletion logic in Listview

* add crud-notifications test project

* update deletion solution to be more pragmatic at scale

* update bug fix to be more verbose

* minor updates to copy

* remove log

* init

* updated delete notif tests

* update usage of deleteAll utility

* update test.yml to include new test file

* remove onconnect and unnecessary try catch

* comments

* update gitignore

* update tests and schema.graphql

* remove headless false flag

* remove unnecessary closure, update failing test

* remove unnecessary try/catch block

* fix test add throw statement to errors

* add waitForNaigation to beforeEach to avoid navigation destroying evaluation context

* remove navigation in beforeAll altogether

* add acess control headers to fix ff preflight errors

* sub out fetch for node-fetch and circumvent weird preflight issues via page.evaluate

* remove page argument from seedData fn

* update yarn.lock

* simplify code by exporting deleteAllData and moving projectRoot resolution
  • Loading branch information
gwyneplaine authored Aug 24, 2021
1 parent 2e3f366 commit 3ecbd0c
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ jobs:
DATABASE_URL: 'file:./test.db'
strategy:
matrix:
test: ['init.test.ts']
test: ['init.test.ts', 'list-view-crud.test.ts']
fail-fast: false
steps:
- name: Checkout Repo
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ temp/

# SQLite databases
*.db
*.db-journal

# Generated files from build process
robots.txt
Expand Down
126 changes: 126 additions & 0 deletions tests/admin-ui-tests/list-view-crud.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Browser, Page } from 'playwright';
import fetch from 'node-fetch';
import { adminUITests, deleteAllData } from './utils';

adminUITests('./tests/test-projects/crud-notifications', browserType => {
let browser: Browser = undefined as any;
let page: Page = undefined as any;
const seedData = async (query: string, variables?: Record<string, any>) => {
try {
const { errors } = await fetch('http://localhost:3000/api/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query,
variables,
}),
}).then(res => res.json());
if (errors) {
throw errors;
}
} catch (e) {
console.log(e);
throw e;
}
};

beforeAll(async () => {
browser = await browserType.launch();
page = await browser.newPage();
});
beforeEach(async () => {
// Drop the database
await deleteAllData('./tests/test-projects/crud-notifications');
});

test('Complete deletion success, only shows the successful deletion prompt', async () => {
// hack for gql syntax highlighting
const gql = String.raw;
const query = gql`
mutation CreateTaskItem {
createTask(data: { label: "you can delete me" }) {
id
label
}
}
`;
await seedData(query);
await Promise.all([page.waitForNavigation(), page.goto('http://localhost:3000/tasks')]);
await page.waitForSelector('tbody tr:first-of-type td:first-of-type label');
await page.click('tbody tr:first-of-type td:first-of-type label');
await page.waitForSelector('button:has-text("Delete")');
await page.click('button:has-text("Delete")');
await page.click('div[role="dialog"] button:has-text("Delete")');
await page.waitForSelector(
'div[role="alert"] h3:has-text("Deleted 1 of 1 Tasks successfully")'
);
const dialogs = await page.$$('div[role="alert"] > div');
expect(dialogs.length).toBe(1);
});

test('Complete deletion failure, only shows the successful failure prompt', async () => {
// hack for gql syntax highlighting
const gql = String.raw;
const query = gql`
mutation CreateTaskItem {
createTask(data: { label: "do not delete" }) {
id
label
}
}
`;
await seedData(query);
await Promise.all([page.waitForNavigation(), page.goto('http://localhost:3000/tasks')]);
await page.click('tbody tr:first-of-type td:first-of-type label');
await page.click('button:has-text("Delete")');
await page.click('div[role="dialog"] button:has-text("Delete")');
await page.waitForSelector('div[role="alert"] h3:has-text("Failed to delete 1 of 1 Tasks")');
const dialogs = await page.$$('div[role="alert"] > div');
expect(dialogs.length).toBe(1);
});

test('Partial deletion failure', async () => {
// hack for gql syntax highlighting
const gql = String.raw;
const query = gql`
mutation CreateTaskItems($data: [TaskCreateInput!]!) {
createTasks(data: $data) {
id
label
}
}
`;
const variables = {
data: Array.from(Array(75).keys()).map(key => {
if (key >= 50) {
return {
label: `delete me ${key - 50}`,
};
} else {
return {
label: `do not delete ${key}`,
};
}
}),
};
await seedData(query, variables);
await Promise.all([
page.waitForNavigation(),
page.goto('http://localhost:3000/tasks?sortBy=label&page=1'),
]);
await page.click('thead th:first-of-type label');
await page.click('button:has-text("Delete")');
await page.click('div[role="dialog"] button:has-text("Delete")');
await page.waitForSelector('div[role="alert"] h3:has-text("Failed to delete 25 of 50 Tasks")');
await page.waitForSelector(
'div[role="alert"] h3:has-text("Deleted 25 of 50 Tasks successfully")'
);
const dialogs = await page.$$('div[role="alert"] > div');
expect(dialogs.length).toBe(2);
});
afterAll(async () => {
await browser.close();
});
});
1 change: 1 addition & 0 deletions tests/admin-ui-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"@manypkg/find-root": "^1.1.0",
"dotenv": "^10.0.0",
"node-fetch": "^2.6.1",
"tree-kill": "^1.2.2"
}
}
27 changes: 16 additions & 11 deletions tests/admin-ui-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@ import * as playwright from 'playwright';
import { findRootSync } from '@manypkg/find-root';
import dotenv from 'dotenv';

async function deleteAllData(projectDir: string) {
const { PrismaClient } = require(path.join(projectDir, 'node_modules/.prisma/client'));

let prisma = new PrismaClient();

await Promise.all(Object.values(prisma).map((x: any) => x?.deleteMany?.()));

await prisma.$disconnect();
}

const treeKill = promisify(_treeKill);

// this'll take a while
Expand All @@ -29,13 +19,28 @@ const promiseSignal = (): Promise<void> & { resolve: () => void } => {
});
return Object.assign(promise, { resolve: resolve as any });
};
const projectRoot = findRootSync(process.cwd());

export const deleteAllData: (projectDir: string) => Promise<void> = async (projectDir: string) => {
const { PrismaClient } = require(path.resolve(
projectRoot,
projectDir,
'node_modules/.prisma/client'
));

let prisma = new PrismaClient();

await Promise.all(Object.values(prisma).map((x: any) => x?.deleteMany?.()));

await prisma.$disconnect();
};

export const adminUITests = (
pathToTest: string,
tests: (browser: playwright.BrowserType<playwright.Browser>) => void
) => {
const projectRoot = findRootSync(process.cwd());
const projectDir = path.join(projectRoot, pathToTest);

dotenv.config();
describe.each(['dev', 'prod'] as const)('%s', mode => {
let cleanupKeystoneProcess = () => {};
Expand Down
13 changes: 0 additions & 13 deletions tests/test-projects/crud-notifications/keystone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,6 @@ export default config({
db: {
provider: 'sqlite',
url: process.env.DATABASE_URL || 'file:./test.db',
async onConnect(context) {
await context.lists.Task.createMany({
data: [...Array.from(Array(50).keys())].map(key => {
return { label: `do not delete ${key}` };
}),
});

await context.lists.Task.createMany({
data: [...Array.from(Array(25).keys())].map(key => {
return { label: `deletable ${key}` };
}),
});
},
},
lists,
});

0 comments on commit 3ecbd0c

Please sign in to comment.