gristlabs_grist-core/test/nbrowser/DuplicateDocument.ts
Paul Fitzpatrick d99db8d016 (core) move more tests to grist-core
Summary:
 * Tie build and run-time docker base images to a consistent version (buster)
 * Extend the test login system activated by GRIST_TEST_LOGIN to ease porting tests that currently rely on cognito (many)
 * Make org resets work in absence of billing endpoints
 * When in-memory session caches are used, add missing invalidation steps
 * Pass org information through sign-ups/sign-ins more carefully
 * For CORS, explicitly trust GRIST_HOST origin when set
 * Move some fixtures and tests to core, focussing on tests that cover existing failures or are in the set of tests run on deployments
 * Retain regular `test` target to run the test suite directly, without docker
 * Add a `test:smoke` target to run a single simple test without `GRIST_TEST_LOGIN` activated
 * Add a `test:docker` target to run the tests against a grist-core docker image - since tests rely on certain fixture teams/docs, added `TEST_SUPPORT_API_KEY` and `TEST_ADD_SAMPLES` flags to ease porting

The tests ported were `nbrowser` tests: `ActionLog.ts` (the first test I tend to port to anything, out of habit), `Fork.ts` (exercises a lot of doc creation paths), `HomeIntro.ts` (a lot of DocMenu exercise), and `DuplicateDocument.ts` (covers a feature known to be failing prior to this diff, the CORS tweak resolves it).

Test Plan: Manually tested via `buildtools/build_core.sh`. In follow up, I want to add running the `test:docker` target in grist-core's workflows. In jenkins, only the smoke test is run. There'd be an argument for running all tests, but they include particularly slow tests, and are duplicates of tests already run (in different configuration admittedly), so I'd like to try first just using them in grist-core to gate updates to any packaged version of Grist (the docker image currently).

Reviewers: alexmojaki

Reviewed By: alexmojaki

Subscribers: alexmojaki

Differential Revision: https://phab.getgrist.com/D3176
2021-12-10 18:33:07 -05:00

204 lines
9.6 KiB
TypeScript

import * as gu from 'test/nbrowser/gristUtils';
import { setupTestSuite } from 'test/nbrowser/testUtils';
import { assert, driver, Key } from 'mocha-webdriver';
describe("DuplicateDocument", function() {
this.timeout(20000);
const cleanup = setupTestSuite({team: true});
it("should duplicate a document with the Duplicate-Document option", async function() {
const session = await gu.session().teamSite.login();
await session.tempDoc(cleanup, 'Hello.grist');
await session.tempWorkspace(cleanup, 'Test Workspace');
// Open the share menu and click item to work on a copy.
await driver.find('.test-tb-share').click();
await driver.find('.test-save-copy').click();
// Should not allow saving a copy to an empty name.
await driver.findWait('.test-modal-dialog', 1000);
const nameElem = await driver.findWait('.test-copy-dest-name:focus', 200);
await nameElem.sendKeys(Key.DELETE);
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), 'true');
await nameElem.sendKeys(' ');
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), 'true');
// As soon as the textbox is non-empty, the Save button should become enabled.
await nameElem.sendKeys('a');
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), null);
// Save a copy with a proper name.
await gu.completeCopy({destName: 'DuplicateTest1'});
// check the breadcrumbs reflect new document name, and the doc is not empty.
assert.equal(await driver.find('.test-bc-doc').value(), 'DuplicateTest1');
assert.equal(await gu.getCell({col: 'A', rowNum: 1}).getText(), 'hello');
});
it("should create a fork with Work-on-a-Copy option", async function() {
// Main user logs in and import a document
const session = await gu.session().teamSite.login();
await session.tempDoc(cleanup, 'Hello.grist');
// Open the share menu and click item to work on a copy.
await driver.find('.test-tb-share').click();
await driver.find('.test-work-on-copy').click();
await gu.waitForUrl(/~/);
await gu.waitForDocToLoad();
// check document is a fork
assert.equal(await driver.find('.test-unsaved-tag').isPresent(), true);
});
// The URL ID of a document copy (named "DuplicateTest2") which we create below and then use in
// several subsequent test cases.
let urlId: string;
it("should allow saving the fork as a new copy", async function() {
// Make a change to the fork to ensure it's saved.
await gu.getCell({col: 'A', rowNum: 1}).click();
await driver.sendKeys('hello to duplicates', Key.ENTER);
await driver.find('.test-tb-share').click();
await driver.find('.test-save-copy').click();
await gu.completeCopy({destName: 'DuplicateTest2'});
urlId = (await gu.getCurrentUrlId())!;
// check the breadcrumbs reflect new document name, and the doc contains our change.
assert.equal(await driver.find('.test-bc-doc').value(), 'DuplicateTest2');
assert.equal(await gu.getCell({col: 'A', rowNum: 1}).getText(), 'hello to duplicates');
});
it("should offer a choice of orgs when user is owner", async function() {
await driver.find('.test-tb-share').click();
await driver.find('.test-save-copy').click();
await driver.findWait('.test-modal-dialog', 1000);
assert.equal(await driver.find('.test-copy-dest-name').value(), 'DuplicateTest2 (copy)');
assert.equal(await driver.find('.test-copy-dest-org').isPresent(), true);
await driver.find('.test-copy-dest-org .test-select-open').click();
assert.includeMembers(await driver.findAll('.test-select-menu li', (el) => el.getText()),
['Personal', 'Test Grist', 'Test2 Grist']);
await driver.sendKeys(Key.ESCAPE);
// Check the list of workspaces in org
await driver.findWait('.test-copy-dest-workspace .test-select-open', 1000).click();
assert.includeMembers(await driver.findAll('.test-select-menu li', (el) => el.getText()),
['Home', 'Test Workspace']);
await driver.sendKeys(Key.ESCAPE);
// Switch the org and check that workspaces get updated.
await driver.find('.test-copy-dest-org .test-select-open').click();
await driver.findContent('.test-select-menu li', 'Test2 Grist').click();
await driver.findWait('.test-copy-dest-workspace .test-select-open', 1000).click();
assert.sameMembers(await driver.findAll('.test-select-menu li', (el) => el.getText()),
['Home']);
await driver.sendKeys(Key.ESCAPE);
await driver.sendKeys(Key.ESCAPE);
});
it("should not offer a choice of org when user is not owner", async function() {
const api = gu.session().teamSite.createHomeApi();
const session2 = gu.session().teamSite.user('user2');
await api.updateDocPermissions(urlId, {users: {
[session2.email]: 'viewers',
}});
await session2.login();
await session2.loadDoc(`/doc/${urlId}`);
await driver.find('.test-tb-share').click();
await driver.find('.test-save-copy').click();
await driver.findWait('.test-modal-dialog', 1000);
assert.equal(await driver.find('.test-copy-dest-name').value(), 'DuplicateTest2 (copy)');
// No choice of orgs
await gu.waitForServer();
assert.equal(await driver.find('.test-copy-dest-org').isPresent(), false);
// We don't happen to have write access to any workspace either.
assert.equal(await driver.find('.test-copy-dest-workspace').isPresent(), false);
assert.match(await driver.find('.test-copy-warning').getText(),
/You do not have write access to this site/);
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), 'true');
await driver.sendKeys(Key.ESCAPE);
});
it("should offer a choice of orgs when doc is public", async function() {
const session = await gu.session().teamSite.login();
const api = session.createHomeApi();
// But if the doc is public, then users can copy it out.
await api.updateDocPermissions(urlId, {users: {
'everyone@getgrist.com': 'viewers',
}});
const session2 = gu.session().teamSite.user('user2');
await gu.session().teamSite2.createHomeApi().updateOrgPermissions('current', {users: {
[session2.email]: 'owners',
}});
await session2.login();
await session2.loadDoc(`/doc/${urlId}`);
await driver.find('.test-tb-share').click();
await driver.find('.test-save-copy').click();
await driver.findWait('.test-modal-dialog', 1000);
assert.equal(await driver.find('.test-copy-dest-name').value(), 'DuplicateTest2 (copy)');
// We can now switch between orgs.
assert.equal(await driver.find('.test-copy-dest-org').isPresent(), true);
// But we still don't have any writable workspaces on the current site.
await gu.waitForServer();
assert.equal(await driver.find('.test-copy-dest-workspace').isPresent(), false);
assert.match(await driver.find('.test-copy-warning').getText(),
/You do not have write access to this site/);
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), 'true');
// We see some good orgs.
await driver.find('.test-copy-dest-org .test-select-open').click();
assert.includeMembers(await driver.findAll('.test-select-menu li', (el) => el.getText()),
['Personal', 'Test Grist', 'Test2 Grist']);
// Switching to an accessible regular org shows workspaces.
await driver.findContent('.test-select-menu li', 'Test2 Grist').click();
await gu.waitForServer();
await driver.find('.test-copy-dest-workspace .test-select-open').click();
assert.sameMembers(await driver.findAll('.test-select-menu li', (el) => el.getText()),
['Home']);
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), null);
// And saving to another org actually works.
await gu.completeCopy();
assert.equal(await driver.find('.test-dm-org').getText(), 'Test2 Grist');
assert.equal(await driver.find('.test-bc-doc').value(), 'DuplicateTest2 (copy)');
assert.equal(await driver.find('.test-bc-workspace').getText(), 'Home');
assert.equal(await gu.getCell({col: 'A', rowNum: 1}).getText(), 'hello to duplicates');
});
it("should allow saving a public doc to the personal org", async function() {
const session2 = gu.session().teamSite.user('user2');
await session2.login();
await session2.loadDoc(`/doc/${urlId}`);
// Open the "Duplicate Document" dialog.
await driver.find('.test-tb-share').click();
await driver.find('.test-save-copy').click();
await driver.findWait('.test-modal-dialog', 1000);
assert.equal(await driver.find('.test-copy-dest-name').value(), 'DuplicateTest2 (copy)');
// Switching to personal org shows no workspaces but no errors either.
await driver.find('.test-copy-dest-org .test-select-open').click();
await driver.findContent('.test-select-menu li', 'Personal').click();
await gu.waitForServer();
assert.equal(await driver.find('.test-copy-dest-workspace').isPresent(), false);
assert.equal(await driver.find('.test-copy-warning').isPresent(), false);
assert.equal(await driver.find('.test-modal-confirm').getAttribute('disabled'), null);
// Save; it should succeed and open a same-looking document in alternate user's personal org.
const name = session2.name;
await gu.completeCopy({destName: `DuplicateTest2 ${name} Copy`});
assert.equal(await driver.find('.test-dm-org').getText(), `@${name}`);
assert.equal(await driver.find('.test-bc-doc').value(), `DuplicateTest2 ${name} Copy`);
assert.equal(await driver.find('.test-bc-workspace').getText(), 'Home');
assert.equal(await gu.getCell({col: 'A', rowNum: 1}).getText(), 'hello to duplicates');
assert.notEqual(await gu.getCurrentUrlId(), urlId);
});
});