(core) Adding tutorial card

Summary:
For now only html stub and docList adjustement for showing a tutorial card.
It will be used in future diffs after tutorial implementation.

Test Plan: Manual

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3750
This commit is contained in:
Jarosław Sadziński
2023-03-28 18:11:40 +02:00
parent 6b5c178953
commit a317a727c8
20 changed files with 425 additions and 31 deletions

View File

@@ -30,6 +30,19 @@ describe('DocTutorial', function () {
session = await gu.session().anon.login();
});
it('shows a tutorial card', async function() {
await session.loadRelPath('/');
await gu.waitForDocMenuToLoad();
await gu.skipWelcomeQuestions();
assert.isTrue(await driver.find('.test-tutorial-card-content').isDisplayed());
// Can dismiss it.
await driver.find('.test-tutorial-card-close').click();
assert.isFalse((await driver.findAll('.test-tutorial-card-content')).length > 0);
// When dismissed, we can see link in the menu.
assert.isTrue(await driver.find('.test-dm-basic-tutorial').isDisplayed());
});
it('redirects user to log in', async function() {
await session.loadDoc(`/doc/${doc.id}`, false);
await gu.checkLoginPage();
@@ -45,6 +58,34 @@ describe('DocTutorial', function () {
afterEach(() => gu.checkForErrors());
it('shows a tutorial card', async function() {
await session.loadRelPath('/');
await gu.waitForDocMenuToLoad();
await gu.skipWelcomeQuestions();
// Make sure we have clean start.
await driver.executeScript('resetSeenPopups();');
await gu.waitForServer();
await driver.navigate().refresh();
await gu.waitForDocMenuToLoad();
// Make sure we see the card.
assert.isTrue(await driver.find('.test-tutorial-card-content').isDisplayed());
// And can dismiss it.
await driver.find('.test-tutorial-card-close').click();
assert.isFalse((await driver.findAll('.test-tutorial-card-content')).length > 0);
// When dismissed, we can see link in the menu.
assert.isTrue(await driver.find('.test-dm-basic-tutorial').isDisplayed());
// Prefs are preserved after reload.
await driver.navigate().refresh();
await gu.waitForDocMenuToLoad();
assert.isFalse((await driver.findAll('.test-tutorial-card-content')).length > 0);
assert.isTrue(await driver.find('.test-dm-basic-tutorial').isDisplayed());
});
it('creates a fork the first time the document is opened', async function() {
await session.loadDoc(`/doc/${doc.id}`);
await driver.wait(async () => {

View File

@@ -248,7 +248,7 @@ describe('HomeIntro', function() {
async function testSelectedExamplesPage() {
// Click Examples & Templates in left panel.
await driver.findContent('.test-dm-templates-page', /Examples & Templates/).click();
await driver.find('.test-dm-templates-page').click();
await gu.waitForDocMenuToLoad();
// Check Featured Templates are shown at the top of the page.

View File

@@ -1977,6 +1977,7 @@ export class Session {
freshAccount?: boolean,
isFirstLogin?: boolean,
showTips?: boolean,
skipTutorial?: boolean, // By default true
retainExistingLogin?: boolean}) {
// Optimize testing a little bit, so if we are already logged in as the expected
// user on the expected org, and there are no options set, we can just continue.
@@ -1994,6 +1995,11 @@ export class Session {
}
await server.simulateLogin(this.settings.name, this.settings.email, this.settings.orgDomain,
{isFirstLogin: false, cacheCredentials: true, ...options});
if (options?.skipTutorial ?? true) {
await dismissTutorialCard();
}
return this;
}
@@ -2033,10 +2039,7 @@ export class Session {
if (wait === 'skipWelcomeQuestions') {
// When waitForDocMenuToLoad() returns, welcome questions should also render, so that we
// don't need to wait extra for them.
if (await driver.find('.test-welcome-questions').isPresent()) {
await driver.sendKeys(Key.ESCAPE);
assert.equal(await driver.find('.test-welcome-questions').isPresent(), false);
}
await skipWelcomeQuestions();
}
}
@@ -2803,12 +2806,34 @@ export async function dismissBehavioralPrompts() {
}
/**
* Dismisses all card popups that are present.
*
* Optionally takes a `waitForServerTimeoutMs`, which may be null to skip waiting
* after closing each popup.
* Dismisses any tutorial card that might be active.
*/
export async function dismissCardPopups(waitForServerTimeoutMs: number | null = 2000) {
export async function dismissTutorialCard() {
// If there is something in our way, we can't do it.
if (await driver.find('.test-welcome-questions').isPresent()) {
return;
}
if (await driver.find('.test-tutorial-card-close').isPresent()) {
if (await driver.find('.test-tutorial-card-close').isDisplayed()) {
await driver.find('.test-tutorial-card-close').click();
}
}
}
/**
* Dismisses coaching call if needed.
*/
export async function dismissCoachingCall() {
const selector = '.test-coaching-call .test-popup-close-button';
if ((await driver.findAll(selector)).length) {
await driver.find(selector).click();
}
}
/**
* Dismisses all card popups that are present.
*/
export async function dismissCardPopups(waitForServerTimeoutMs: number | null = 2000) {
let i = 0;
const max = 10;
@@ -2820,6 +2845,7 @@ export async function dismissBehavioralPrompts() {
}
}
/**
* Confirms that anchor link was used for navigation.
*/
@@ -2920,6 +2946,17 @@ export function withComments() {
});
}
/**
* Helper to scroll creator panel top or bottom. By default bottom.
*/
export function scrollPanel(top = false): WebElementPromise {
return new WebElementPromise(driver,
driver.executeScript((top: number) => {
document.getElementsByClassName('test-config-container')[0].scrollTop = top ? 0 : 10000;
}, top)
);
}
/**
* Helper to revert ACL changes. It first saves the current ACL data, and
* then removes everything and adds it back.
@@ -2968,6 +3005,13 @@ export async function setRangeFilterBound(minMax: 'min'|'max', value: string|{re
}
}
export async function skipWelcomeQuestions() {
if (await driver.find('.test-welcome-questions').isPresent()) {
await driver.sendKeys(Key.ESCAPE);
assert.equal(await driver.find('.test-welcome-questions').isPresent(), false);
}
}
} // end of namespace gristUtils
stackWrapOwnMethods(gristUtils);