@salesforcedevs/sfdocs-e2e 0.6.132-linkfix-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +63 -0
  2. package/bin/run-e2e.js +115 -0
  3. package/common-wdio.conf.js +402 -0
  4. package/package.json +40 -0
  5. package/portal-wdio.conf.js +7 -0
  6. package/search-wdio.conf.js +10 -0
  7. package/src/content-repo/pageobjects/home.page.ts +55 -0
  8. package/src/content-repo/specs/componentSpecification.test.ts +287 -0
  9. package/src/content-repo/specs/guideAndReferencePage.test.ts +46 -0
  10. package/src/content-repo/specs/homepage.test.ts +47 -0
  11. package/src/content-repo/specs/media-mapper.test.ts +18 -0
  12. package/src/content-repo/specs/navHeader.test.ts +79 -0
  13. package/src/content-repo/specs/sitemap.test.ts +58 -0
  14. package/src/content-repo/specs/tabset.test.ts +81 -0
  15. package/src/portal/pageobjects/docs.apis.page.ts +23 -0
  16. package/src/portal/pageobjects/docs.page.ts +18 -0
  17. package/src/portal/pageobjects/help-page/ScopeSeachTest.page.ts +20 -0
  18. package/src/portal/specs/docs.api.test.ts +68 -0
  19. package/src/portal/specs/docs.test.ts +84 -0
  20. package/src/portal/specs/media-mapper.test.ts +42 -0
  21. package/src/portal/specs/scope.search.guide.test.ts +33 -0
  22. package/src/portal/specs/scope.search.reference.test.ts +37 -0
  23. package/src/shared/pageobjects/api-redoc-reference.page.ts +40 -0
  24. package/src/shared/pageobjects/callout.ts +24 -0
  25. package/src/shared/pageobjects/doc-phase-config.ts +106 -0
  26. package/src/shared/pageobjects/docs-content-layout.ts +17 -0
  27. package/src/shared/pageobjects/error.page.ts +14 -0
  28. package/src/shared/pageobjects/guide.page.ts +24 -0
  29. package/src/shared/pageobjects/overview.page.ts +20 -0
  30. package/src/shared/pageobjects/page.ts +115 -0
  31. package/src/shared/pageobjects/reference.page.ts +41 -0
  32. package/src/shared/specs/anchorHeading.test.ts +21 -0
  33. package/src/shared/specs/banner.test.ts +66 -0
  34. package/src/shared/specs/breadcrumbs.test.ts +45 -0
  35. package/src/shared/specs/calloutContent.test.ts +102 -0
  36. package/src/shared/specs/codeBlock.test.ts +44 -0
  37. package/src/shared/specs/devCenterLink.test.ts +42 -0
  38. package/src/shared/specs/docPhase.test.ts +127 -0
  39. package/src/shared/specs/errorRoutes.test.ts +24 -0
  40. package/src/shared/specs/guides.test.ts +333 -0
  41. package/src/shared/specs/layout-tests.ts +38 -0
  42. package/src/shared/specs/overview.test.ts +82 -0
  43. package/src/shared/specs/page-title.test.ts +12 -0
  44. package/src/shared/specs/redoc-reference.test.ts +170 -0
  45. package/src/shared/specs/reference.test.ts +281 -0
  46. package/src/shared/specs/video.test.ts +31 -0
  47. package/static-portal-wdio.conf.js +50 -0
  48. package/tsconfig.json +26 -0
  49. package/wdio.conf.js +6 -0
@@ -0,0 +1,23 @@
1
+ import Page from '../../shared/pageobjects/page';
2
+
3
+ /**
4
+ * sub page containing specific selectors and methods for a specific page
5
+ */
6
+ export default class DocsApisPage extends Page {
7
+ constructor(url?: string) {
8
+ if (url) {
9
+ super(url);
10
+ } else {
11
+ super('/docs/apis');
12
+ }
13
+ }
14
+
15
+ async getSidebarContent(): Promise<WebdriverIO.Element> {
16
+ return $('>>>div.tile-selected');
17
+ }
18
+
19
+ async waitPageLoad(): Promise<void> {
20
+ const mainContent = await $('>>>#maincontent');
21
+ mainContent.waitForDisplayed({ timeout: 10000 });
22
+ }
23
+ }
@@ -0,0 +1,18 @@
1
+ import Page from '../../shared/pageobjects/page';
2
+
3
+ /**
4
+ * sub page containing specific selectors and methods for a specific page
5
+ */
6
+ export default class DocsPage extends Page {
7
+ constructor(url?: string) {
8
+ if (url) {
9
+ super(url);
10
+ } else {
11
+ super('/docs');
12
+ }
13
+ }
14
+
15
+ async waitPageLoad(): Promise<void> {
16
+ await (await $('>>>#maincontent')).waitForDisplayed();
17
+ }
18
+ }
@@ -0,0 +1,20 @@
1
+ import Page from '../../../shared/pageobjects/page';
2
+
3
+ /**
4
+ * ScopeSeachTestPage https://developer.salesforce.com/docs/platform/graphql/guide/graphql-about.html
5
+ */
6
+ class ScopeSeachTestPage extends Page {
7
+ constructor(url: string) {
8
+ super(url);
9
+ }
10
+
11
+ async getTitle(): Promise<WebdriverIO.Element> {
12
+ return $('>>>h2.dx-text-heading-2');
13
+ }
14
+
15
+ async waitPageLoad(): Promise<void> {
16
+ await (await $('>>>doc-content-layout')).waitForDisplayed();
17
+ }
18
+ }
19
+
20
+ export default ScopeSeachTestPage;
@@ -0,0 +1,68 @@
1
+ import DocsApisPage from '../pageobjects/docs.apis.page';
2
+ import layoutTest from '../../shared/specs/layout-tests';
3
+ import DocsContentLayout from '../../shared/pageobjects/docs-content-layout';
4
+
5
+ let page: DocsApisPage;
6
+ describe('/docs page basic display', () => {
7
+ beforeEach(async () => {
8
+ page = new DocsApisPage('/docs/apis');
9
+ page.open();
10
+ return await page.waitPageLoad();
11
+ });
12
+
13
+ layoutTest(page);
14
+
15
+ it('should have the right title', () => {
16
+ expect(browser).toHaveTitle('Salesforce Developers');
17
+ });
18
+
19
+ it('should display project cards', async () => {
20
+ const cards = $('dx-section.api-landing-section_list')
21
+ .then((section) => section.$('dx-grid'))
22
+ .then((grid) => grid.$$('dx-card-docs'));
23
+
24
+ expect((await cards).length).not.toBe(0);
25
+ });
26
+
27
+ it('should display project cards click on overview - test first overview card', async () => {
28
+ const projectCards = await page.projectCardsWithGuides;
29
+ projectCards.forEach(async (cardElem, index) => {
30
+ if (index === 1) {
31
+ const guideButton = await cardElem.$('dx-button[href*=overview]');
32
+ await guideButton.click();
33
+ await DocsContentLayout.waitForContentLayoutSidebar();
34
+ const heading = await DocsContentLayout.getSidebarHeading();
35
+
36
+ expect(heading).toBe('Overview');
37
+ }
38
+ });
39
+ });
40
+
41
+ it('should display project cards click on guides - test first guide card', async () => {
42
+ const projectCards = await page.projectCardsWithGuides;
43
+ projectCards.forEach(async (cardElem, index) => {
44
+ if (index === 1) {
45
+ const guideButton = await cardElem.$('dx-button[href*=guide]');
46
+ await guideButton.click();
47
+ await DocsContentLayout.waitForContentLayoutSidebar();
48
+ const heading = await DocsContentLayout.getSidebarHeading();
49
+
50
+ expect(heading).toBe('Guides');
51
+ }
52
+ });
53
+ });
54
+
55
+ it('should display project cards click on references - test first references card', async () => {
56
+ const projectCards = await page.projectCardsWithReferences;
57
+ projectCards.forEach(async (cardElem, index) => {
58
+ if (index === 1) {
59
+ const refButton = await cardElem.$('dx-button[href*=references]');
60
+ await refButton.click();
61
+ await DocsContentLayout.waitForContentLayoutSidebar();
62
+ const heading = await DocsContentLayout.getSidebarHeading();
63
+
64
+ expect(heading).toBe('References');
65
+ }
66
+ });
67
+ });
68
+ });
@@ -0,0 +1,84 @@
1
+ import OpenPage from '../pageobjects/docs.page';
2
+ import layoutTest from '../../shared/specs/layout-tests';
3
+
4
+ let page: OpenPage;
5
+
6
+ describe('/docs page basic display > ', () => {
7
+ beforeEach(async () => {
8
+ page = new OpenPage('/docs');
9
+ page.open();
10
+ await page.waitPageLoad();
11
+ });
12
+
13
+ layoutTest(page);
14
+
15
+ it('should have the right title', () => {
16
+ expect(browser).toHaveTitle('Salesforce Developers');
17
+ });
18
+
19
+ it('Should display tabs ', async () => {
20
+ const tabSection = await $('#maincontent div dx-section:nth-child(2)');
21
+
22
+ expect(await tabSection.isDisplayed()).toBeTruthy();
23
+ expect(await tabSection.getText()).toContain('FEATURED');
24
+ expect(await tabSection.getText()).toContain('ALL');
25
+ });
26
+
27
+ it('Should display Release notes and Browse APIS tabs ', async () => {
28
+ const tabSection = await $('>>>#maincontent div dx-section:nth-child(3)');
29
+
30
+ expect(await tabSection.isDisplayed()).toBeTruthy();
31
+ expect(await tabSection).toHaveLinkContaining('/docs/apis');
32
+ expect(await tabSection.getText()).toContain('Read Release Notes');
33
+ expect(await tabSection.getText()).toContain('Browse APIs');
34
+ });
35
+
36
+ it('Tab : FEATURED should present and also clickable', async () => {
37
+ const selectedTab = await $('dx-button.docs-tab-link.selected');
38
+
39
+ expect(await selectedTab.isClickable()).toBeTruthy();
40
+ expect(await selectedTab.getText()).toEqual('FEATURED');
41
+ expect(await selectedTab).toHaveLinkContaining('/docs');
42
+ });
43
+
44
+ it('Tab : ALL should present and also clickable', async () => {
45
+ const nonselectedTab = await $('dx-button.docs-tab-link:nth-child(2)');
46
+
47
+ expect(await nonselectedTab.isClickable()).toBeTruthy();
48
+ expect(await nonselectedTab.getText()).toEqual('ALL');
49
+ expect(await nonselectedTab).toHaveLinkContaining('/docs/list');
50
+ });
51
+
52
+ it('Docs list : Check if docs cards are getting added', async () => {
53
+ // Selecting 'All' in /docs page.
54
+ const nonselectedTab = await $('dx-button.docs-tab-link:nth-child(2)');
55
+ nonselectedTab.click();
56
+ await page.waitPageLoad();
57
+ const docsCards = await $$('>>>.docs-grid-container > dx-grid > dx-card-docs.docs-card');
58
+ await (await docsCards[0]).scrollIntoView();
59
+ expect(await nonselectedTab.getAttribute('class')).toEqual('docs-tab-link selected');
60
+ // await browser.waitUntil(
61
+ // async () =>
62
+ // (await (await docsCards[0].$('>>> dx-card-title > h3')).getText()) ===
63
+ // 'A Guide to Sharing Architecture',
64
+ // {
65
+ // timeout: 25000,
66
+ // timeoutMsg: 'Expected Couch db docs could not be loaded',
67
+ // },
68
+ // );
69
+ // expect(await (await docsCards[0].$('>>> dx-card-title > h3')).getText()).toEqual(
70
+ // 'A Guide to Sharing Architecture',
71
+ // );
72
+ });
73
+
74
+ it('Docs list : Search for invalid text to show no product result', async () => {
75
+ page = new OpenPage('/docs/list?filter_text=tableau%20xyz&lang=en-us&page=1');
76
+ page.open();
77
+ await page.waitPageLoad();
78
+ const emptyDocsMsg = await $('>>>dx-empty-state div > h3');
79
+ expect(await emptyDocsMsg.getText()).toEqual('Beep boop. That did not compute.');
80
+ expect(await (await $('>>>dx-empty-state div > p')).getText()).toEqual(
81
+ 'Sorry, no results were found for your search "tableau xyz"',
82
+ );
83
+ });
84
+ });
@@ -0,0 +1,42 @@
1
+ import GuidePage from '../../shared/pageobjects/guide.page';
2
+
3
+ const mediaMapperTest = async (url: string, alt: string, expectedSrc: string) => {
4
+ const page = new GuidePage(url);
5
+ page.open();
6
+ await page.waitPageLoad();
7
+
8
+ const srcValue = await $(`[alt="${alt}"]`).getAttribute('src');
9
+
10
+ expect(srcValue).toMatch(expectedSrc);
11
+ };
12
+
13
+ describe('/docs Media Mapper > ', () => {
14
+ it('should show images with the cdn image when cdn image mapping is enabled', async () => {
15
+ const url = 'docs/plugin-development/guide/markdown-cheatsheet.html';
16
+ const alt = 'SalesforceDocs';
17
+ const expectedSrc =
18
+ 'https://a.sfdcstatic.com/developer-website/sfdocs/example-repository/media/salesforcedocs.png';
19
+
20
+ await mediaMapperTest(url, alt, expectedSrc);
21
+ });
22
+
23
+ it('should show images with the cdn image in references', async () => {
24
+ const url =
25
+ 'docs/commerce/ja-jp/flex-references-loc/references/manual-ref/find-sfra-tools.html';
26
+ const alt = 'Create Branch';
27
+ const expectedSrc =
28
+ 'https://a.sfdcstatic.com/developer-website/sfdocs/example-repository/media/ja-jp/clone-create-branch.gif';
29
+
30
+ await mediaMapperTest(url, alt, expectedSrc);
31
+ });
32
+
33
+ it('should show images with the cdn image in other locales', async () => {
34
+ const url =
35
+ 'docs/commerce/ja-jp/flex-references-loc/references/manual-ref/commerce-cloud-api-overview.html';
36
+ const alt = 'Clone Repo';
37
+ const expectedSrc =
38
+ 'https://a.sfdcstatic.com/developer-website/sfdocs/example-repository/media/ja-jp/clone-repo.png';
39
+
40
+ await mediaMapperTest(url, alt, expectedSrc);
41
+ });
42
+ });
@@ -0,0 +1,33 @@
1
+ import ScopeSeachTestPage from '../pageobjects/help-page/ScopeSeachTest.page';
2
+
3
+ let page: ScopeSeachTestPage;
4
+
5
+ describe.skip('Scope Search Reference Test', () => {
6
+ beforeEach(async () => {
7
+ page = new ScopeSeachTestPage(
8
+ 'https://developer.salesforce.com/docs/platform/graphql/guide/',
9
+ );
10
+ page.open();
11
+ await page.waitPageLoad();
12
+ });
13
+
14
+ it('should send notfication if the scope search is not Working', async () => {
15
+ await $('doc-content-layout')
16
+ .then((layout) => layout.shadow$('div > dx-sidebar'))
17
+ .then((sidebar) => sidebar.waitForDisplayed());
18
+ const sidebar = await (await $('doc-content-layout')).shadow$('div > dx-sidebar');
19
+ const dxInput = await sidebar.shadow$(
20
+ 'div > div.sidebar-header > div.search > dx-sidebar-search',
21
+ );
22
+ const dxinput1 = await dxInput.shadow$('dx-dropdown > dx-input');
23
+ const searchBox = await dxinput1.shadow$('input');
24
+ await searchBox.click();
25
+ await browser.keys('Support');
26
+ const trees = await sidebar.shadow$(
27
+ 'div.container div.sidebar-content dx-sidebar-search-result',
28
+ );
29
+ const servicesTree = await trees.shadow$('span > span');
30
+ const searchResults = await servicesTree.getText();
31
+ expect(searchResults.length).toBeGreaterThan(0);
32
+ });
33
+ });
@@ -0,0 +1,37 @@
1
+ import ScopeSeachTestPage from '../pageobjects/help-page/ScopeSeachTest.page';
2
+
3
+ let page: ScopeSeachTestPage;
4
+
5
+ describe.skip('Scope Search Reference Test', () => {
6
+ beforeEach(async () => {
7
+ page = new ScopeSeachTestPage(
8
+ 'https://developer.salesforce.com/docs/platform/graphql/references/',
9
+ );
10
+ page.open();
11
+ await page.waitPageLoad();
12
+ });
13
+
14
+ it('should send notfication if the scope search is not Working for reference Page ', async () => {
15
+ await $('doc-amf-reference')
16
+ .then((additional) => additional.shadow$('doc-content-layout'))
17
+ .then((layout) => layout.shadow$('div > dx-sidebar'))
18
+ .then((sidebar) => sidebar.waitForDisplayed());
19
+
20
+ const layer = await (await $('doc-amf-reference')).shadow$('doc-content-layout');
21
+ const sidebar = await layer.shadow$('div > dx-sidebar');
22
+
23
+ const dxInput = await sidebar.shadow$(
24
+ 'div > div.sidebar-header > div.search > dx-sidebar-search',
25
+ );
26
+ const dxinput1 = await dxInput.shadow$('dx-dropdown > dx-input');
27
+ const searchBox = await dxinput1.shadow$('input');
28
+ await searchBox.click();
29
+ await browser.keys('Graphql');
30
+ const trees = await sidebar.shadow$(
31
+ 'div.container div.sidebar-content dx-sidebar-search-result',
32
+ );
33
+ const servicesTree = await trees.shadow$('span > span');
34
+ const searchResults = await servicesTree.getText();
35
+ expect(searchResults.length).toBeGreaterThan(0);
36
+ });
37
+ });
@@ -0,0 +1,40 @@
1
+ import Page from './page';
2
+ /**
3
+ * Redoc API reference page object so that we can use all centralized methods.
4
+ */
5
+ class ApiRedocReferencePage extends Page {
6
+ constructor(url?: string) {
7
+ if (url) {
8
+ super(url);
9
+ } else {
10
+ super('/docs/');
11
+ }
12
+ }
13
+
14
+ async waitPageLoad(): Promise<void> {
15
+ await $('doc-redoc-reference > .redoc-container').waitForDisplayed({
16
+ timeout: this.REFERENCE_LOAD_WAIT_TIME,
17
+ });
18
+ }
19
+
20
+ async getApiTitle(): Promise<WebdriverIO.Element> {
21
+ return $('>>>div.api-info > h1');
22
+ }
23
+
24
+ async getSidebar(): Promise<WebdriverIO.Element> {
25
+ return $('.redoc-wrap > .menu-content');
26
+ }
27
+
28
+ async getContent(): Promise<WebdriverIO.Element> {
29
+ return $('.redoc-wrap > .api-content');
30
+ }
31
+
32
+ async getLnbItemByIndex(index: number): Promise<WebdriverIO.Element> {
33
+ const sidebar = await this.getSidebar();
34
+ const scrollbarContainer = sidebar.$('.scrollbar-container');
35
+ const lnbItems = await scrollbarContainer.$$('ul[role="menu"] > li');
36
+ return lnbItems[index];
37
+ }
38
+ }
39
+
40
+ export default ApiRedocReferencePage;
@@ -0,0 +1,24 @@
1
+ import Page from './page';
2
+
3
+ /**
4
+ * sub page containing specific selectors and methods for a specific page
5
+ */
6
+ export class Callout extends Page {
7
+ async waitAndGetDocPhaseParentInGuidePage(): Promise<WebdriverIO.Element> {
8
+ (await $('doc-content-layout')).waitForDisplayed({ timeout: 5000 });
9
+
10
+ return $('doc-content-layout');
11
+ }
12
+
13
+ async waitAndGetListOfCallout(
14
+ sectionsContentLayout: WebdriverIO.Element,
15
+ ): Promise<WebdriverIO.Element[]> {
16
+ (await sectionsContentLayout.shadow$('doc-content-callout')).waitForDisplayed({
17
+ timeout: 5000,
18
+ });
19
+
20
+ return sectionsContentLayout.$$('>>>doc-content-callout');
21
+ }
22
+ }
23
+
24
+ export default new Callout();
@@ -0,0 +1,106 @@
1
+ export const phases = {
2
+ beta: 'beta',
3
+ pilot: 'pilot',
4
+ devPreview: 'devPreview',
5
+ };
6
+
7
+ export const getDocConfigWithPhaseForRedoc = (phase: string): { title: string; body: string } => {
8
+ switch (phase) {
9
+ case phases.beta:
10
+ return {
11
+ title: 'Parent Banner Indicator',
12
+ body: 'This parent banner feature is made available on an AS IS basis and use of this feature is at your sole risk.',
13
+ };
14
+ case phases.pilot:
15
+ return {
16
+ title: 'Reference Banner Indicator',
17
+ body: 'This reference feature is made available on an AS IS basis and use of this feature is at your sole risk.',
18
+ };
19
+ default:
20
+ return {
21
+ title: 'Developer Preview',
22
+ body: 'This dev preview feature is made',
23
+ };
24
+ }
25
+ };
26
+
27
+ export const getDocConfigWithPhase = (phase: string): { title: string; body: string } => {
28
+ switch (phase) {
29
+ case phases.beta:
30
+ return {
31
+ title: 'Beta Indicator',
32
+ body: 'This beta feature is made',
33
+ };
34
+ case phases.pilot:
35
+ return {
36
+ title: 'Pilot Indicator',
37
+ body: 'This pilot feature is made',
38
+ };
39
+ default:
40
+ return {
41
+ title: 'Developer Preview',
42
+ body: 'This dev preview feature is made',
43
+ };
44
+ }
45
+ };
46
+
47
+ export const waitAndGetDocPhaseParentInOverviewPage = async (): Promise<WebdriverIO.Element> => {
48
+ (await $('.content-type-overview')).waitForDisplayed({ timeout: 5000 });
49
+
50
+ return await $('.content-type-overview');
51
+ };
52
+
53
+ export const waitAndGetDocPhaseParentInGuidePage = async (): Promise<WebdriverIO.Element> => {
54
+ (await $('doc-content-layout')).waitForDisplayed({ timeout: 5000 });
55
+
56
+ return await $('doc-content-layout');
57
+ };
58
+
59
+ export const waitAndGetDocPhaseParentInReferencesPage = async (): Promise<WebdriverIO.Element> => {
60
+ (await $('doc-amf-reference')).waitForDisplayed({ timeout: 5000 });
61
+
62
+ const reference = await $('doc-amf-reference');
63
+ return await reference.shadow$('doc-content-layout');
64
+ };
65
+
66
+ export const waitAndGetDocPhaseParentInRedocReferencesPage =
67
+ async (): Promise<WebdriverIO.Element> => {
68
+ (await $('doc-redoc-reference')).waitForDisplayed({ timeout: 5000 });
69
+
70
+ const reference = await $('doc-redoc-reference > .redoc-container');
71
+ return reference;
72
+ };
73
+
74
+ export const assertDocPhaseElements = async (
75
+ parentElement: WebdriverIO.Element,
76
+ phase: string = phases.devPreview,
77
+ ): Promise<void> => {
78
+ const docPhase = await parentElement.$('doc-phase');
79
+ const title = await docPhase.shadow$('.doc-phase-title');
80
+ const body = await docPhase.shadow$('.doc-phase-body');
81
+ const docConfig = getDocConfigWithPhase(phase);
82
+
83
+ expect(await title.getText()).toBe(docConfig.title);
84
+ expect(await body.getText()).toContain(docConfig.body);
85
+ };
86
+
87
+ export const assertDocPhaseElementsForRedoc = async (
88
+ parentElement: WebdriverIO.Element,
89
+ phase: string = phases.devPreview,
90
+ ): Promise<void> => {
91
+ const docPhase = await parentElement.$('doc-phase');
92
+ const title = await docPhase.shadow$('.doc-phase-title');
93
+ const body = await docPhase.shadow$('.doc-phase-body');
94
+ const docConfig = getDocConfigWithPhaseForRedoc(phase);
95
+ expect(await title.getText()).toBe(docConfig.title);
96
+ expect(await body.getText()).toContain(docConfig.body);
97
+ };
98
+
99
+ export const assertDocPhaseUnavailability = async (
100
+ parentElement: WebdriverIO.Element,
101
+ ): Promise<void> => {
102
+ const docPhase = await parentElement.$('doc-phase');
103
+ const isExisting = await docPhase.isExisting();
104
+
105
+ expect(isExisting).toBe(false);
106
+ };
@@ -0,0 +1,17 @@
1
+ class DocsContentLayout {
2
+ SIDEBAR_HEADING_SELECTOR = 'div > div.padding-horizontal > div.header > h1.header-title';
3
+
4
+ async waitForContentLayoutSidebar(): Promise<void> {
5
+ const layout = await $('doc-content-layout');
6
+ const sidebar = await layout.shadow$('div > dx-sidebar');
7
+ await sidebar.waitForDisplayed();
8
+ }
9
+
10
+ async getSidebarHeading(): Promise<string> {
11
+ const sidebar = await (await $('doc-content-layout')).shadow$('div > dx-sidebar');
12
+ const heading = await sidebar.shadow$(this.SIDEBAR_HEADING_SELECTOR);
13
+ return heading.getText();
14
+ }
15
+ }
16
+
17
+ export default new DocsContentLayout();
@@ -0,0 +1,14 @@
1
+ import Page from './page';
2
+
3
+ /**
4
+ * Error page (e.g. 404 / page-not-found)
5
+ */
6
+ export default class ErrorPage extends Page {
7
+ constructor(url?: string) {
8
+ if (url) {
9
+ super(url);
10
+ } else {
11
+ super('/page-not-found');
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,24 @@
1
+ import Page from './page';
2
+
3
+ /**
4
+ * Guide page
5
+ */
6
+ class GuidePage extends Page {
7
+ constructor(url?: string) {
8
+ if (url) {
9
+ super(url);
10
+ } else {
11
+ super('/docs/apis');
12
+ }
13
+ }
14
+
15
+ async getApiTitle(): Promise<WebdriverIO.Element> {
16
+ return $('>>>div.api-title');
17
+ }
18
+
19
+ async waitPageLoad(): Promise<void> {
20
+ await (await $('>>>doc-content-layout')).waitForDisplayed();
21
+ }
22
+ }
23
+
24
+ export default GuidePage;
@@ -0,0 +1,20 @@
1
+ import Page from './page';
2
+
3
+ /**
4
+ * Overview page
5
+ */
6
+ class OverviewPage extends Page {
7
+ constructor(url: string) {
8
+ super(url);
9
+ }
10
+
11
+ async getApiTitle(): Promise<WebdriverIO.Element> {
12
+ return $('>>>h2.dx-text-heading-2');
13
+ }
14
+
15
+ async waitPageLoad(): Promise<void> {
16
+ await (await $('>>>.overview-content')).waitForDisplayed();
17
+ }
18
+ }
19
+
20
+ export default OverviewPage;