app.e2e-spec.ts (angular-11.0.1) | : | app.e2e-spec.ts (angular-11.0.2) | ||
---|---|---|---|---|
import { browser, by, element, ElementFinder } from 'protractor'; | import { browser, by, element, ElementFinder } from 'protractor'; | |||
import { SitePage } from './app.po'; | import { SitePage } from './app.po'; | |||
describe('site App', () => { | describe('site App', () => { | |||
let page: SitePage; | let page: SitePage; | |||
beforeEach(() => { | beforeEach(async () => { | |||
SitePage.setWindowWidth(1050); // Make the window wide enough to show the | await SitePage.setWindowWidth(1050); // Make the window wide enough to sho | |||
SideNav side-by-side. | w the SideNav side-by-side. | |||
page = new SitePage(); | page = new SitePage(); | |||
}); | }); | |||
it('should show features text after clicking "Features"', () => { | it('should show features text after clicking "Features"', async () => { | |||
page.navigateTo(''); | await page.navigateTo(''); | |||
page.click(page.getTopMenuLink('features')); | await page.click(page.getTopMenuLink('features')); | |||
expect(page.getDocViewerText()).toMatch(/Progressive web apps/i); | expect(await page.getDocViewerText()).toMatch(/Progressive web apps/i); | |||
}); | }); | |||
it('should set appropriate window titles', () => { | it('should set appropriate window titles', async () => { | |||
page.navigateTo(''); | await page.navigateTo(''); | |||
expect(browser.getTitle()).toBe('Angular'); | expect(await browser.getTitle()).toBe('Angular'); | |||
page.click(page.getTopMenuLink('features')); | await page.click(page.getTopMenuLink('features')); | |||
expect(browser.getTitle()).toBe('Angular - FEATURES & BENEFITS'); | expect(await browser.getTitle()).toBe('Angular - FEATURES & BENEFITS'); | |||
page.click(page.homeLink); | await page.click(page.homeLink); | |||
expect(browser.getTitle()).toBe('Angular'); | expect(await browser.getTitle()).toBe('Angular'); | |||
}); | }); | |||
it('should not navigate when clicking on nav-item headings (sub-menu toggles)' , () => { | it('should not navigate when clicking on nav-item headings (sub-menu toggles)' , async () => { | |||
// Show the sidenav. | // Show the sidenav. | |||
page.navigateTo('docs'); | await page.navigateTo('docs'); | |||
expect(page.locationPath()).toBe('/docs'); | expect(await page.locationPath()).toBe('/docs'); | |||
// Get the top-level nav-item headings (sub-menu toggles). | // Get the top-level nav-item headings (sub-menu toggles). | |||
const navItemHeadings = page.getNavItemHeadings(page.sidenav, 1); | const navItemHeadings = page.getNavItemHeadings(page.sidenav, 1); | |||
// Test all headings (and sub-headings). | // Test all headings (and sub-headings). | |||
expect(navItemHeadings.count()).toBeGreaterThan(0); | expect(await navItemHeadings.count()).toBeGreaterThan(0); | |||
navItemHeadings.each(heading => testNavItemHeading(heading!, 1)); | await navItemHeadings.each(heading => testNavItemHeading(heading!, 1)); | |||
// Helpers | // Helpers | |||
function expectToBeCollapsed(elementFinder: ElementFinder) { | async function expectToBeCollapsed(elementFinder: ElementFinder) { | |||
expect(elementFinder.getAttribute('class')).toMatch(/\bcollapsed\b/); | expect(await elementFinder.getAttribute('class')).toMatch(/\bcollapsed\b/) | |||
expect(elementFinder.getAttribute('class')).not.toMatch(/\bexpanded\b/); | ; | |||
expect(await elementFinder.getAttribute('class')).not.toMatch(/\bexpanded\ | ||||
b/); | ||||
} | } | |||
function expectToBeExpanded(elementFinder: ElementFinder) { | async function expectToBeExpanded(elementFinder: ElementFinder) { | |||
expect(elementFinder.getAttribute('class')).not.toMatch(/\bcollapsed\b/); | expect(await elementFinder.getAttribute('class')).not.toMatch(/\bcollapsed | |||
expect(elementFinder.getAttribute('class')).toMatch(/\bexpanded\b/); | \b/); | |||
expect(await elementFinder.getAttribute('class')).toMatch(/\bexpanded\b/); | ||||
} | } | |||
function testNavItemHeading(heading: ElementFinder, level: number) { | async function testNavItemHeading(heading: ElementFinder, level: number) { | |||
const children = page.getNavItemHeadingChildren(heading, level); | const children = page.getNavItemHeadingChildren(heading, level); | |||
// Headings are initially collapsed. | // Headings are initially collapsed. | |||
expectToBeCollapsed(children); | await expectToBeCollapsed(children); | |||
// Ensure heading does not cause navigation when expanding. | // Ensure heading does not cause navigation when expanding. | |||
page.click(heading); | await page.click(heading); | |||
expectToBeExpanded(children); | await expectToBeExpanded(children); | |||
expect(page.locationPath()).toBe('/docs'); | expect(await page.locationPath()).toBe('/docs'); | |||
// Recursively test child-headings (while this heading is expanded). | // Recursively test child-headings (while this heading is expanded). | |||
const nextLevel = level + 1; | const nextLevel = level + 1; | |||
const childNavItemHeadings = page.getNavItemHeadings(children, nextLevel); | const childNavItemHeadings = page.getNavItemHeadings(children, nextLevel); | |||
childNavItemHeadings.each(childHeading => testNavItemHeading(childHeading! , nextLevel)); | await childNavItemHeadings.each(childHeading => testNavItemHeading(childHe ading!, nextLevel)); | |||
// Ensure heading does not cause navigation when collapsing. | // Ensure heading does not cause navigation when collapsing. | |||
page.click(heading); | await page.click(heading); | |||
expectToBeCollapsed(children); | await expectToBeCollapsed(children); | |||
expect(page.locationPath()).toBe('/docs'); | expect(await page.locationPath()).toBe('/docs'); | |||
} | } | |||
}); | }); | |||
it('should show the tutorial index page at `/tutorial` after jitterbugging thr ough features', () => { | it('should show the tutorial index page at `/tutorial` after jitterbugging thr ough features', async () => { | |||
// check that we can navigate directly to the tutorial page | // check that we can navigate directly to the tutorial page | |||
page.navigateTo('tutorial'); | await page.navigateTo('tutorial'); | |||
expect(page.getDocViewerText()).toMatch(/Tour of Heroes App and Tutorial/i); | expect(await page.getDocViewerText()).toMatch(/Tour of Heroes App and Tutori | |||
al/i); | ||||
// navigate to a different page | // navigate to a different page | |||
page.click(page.getTopMenuLink('features')); | await page.click(page.getTopMenuLink('features')); | |||
expect(page.getDocViewerText()).toMatch(/Progressive web apps/i); | expect(await page.getDocViewerText()).toMatch(/Progressive web apps/i); | |||
// Show the menu | // Show the menu | |||
page.click(page.docsMenuLink); | await page.click(page.docsMenuLink); | |||
// Tutorial folder should still be expanded because this test runs in wide m ode | // Tutorial folder should still be expanded because this test runs in wide m ode | |||
// Navigate to the tutorial introduction via a link in the sidenav | // Navigate to the tutorial introduction via a link in the sidenav | |||
page.click(page.getNavItem(/The Hero Editor/i)); | await page.click(page.getNavItem(/The Hero Editor/i)); | |||
expect(page.getDocViewerText()).toMatch(/The Hero Editor/i); | expect(await page.getDocViewerText()).toMatch(/The Hero Editor/i); | |||
}); | }); | |||
it('should render `{@example}` dgeni tags as `<code-example>` elements with HT | it('should render `{@example}` dgeni tags as `<code-example>` elements with HT | |||
ML escaped content', () => { | ML escaped content', async () => { | |||
page.navigateTo('guide/component-styles'); | await page.navigateTo('guide/component-styles'); | |||
const codeExample = element.all(by.css('code-example')).first(); | const codeExample = element.all(by.css('code-example')).first(); | |||
expect(page.getInnerHtml(codeExample)).toContain('<h1>Tour of Heroes&l t;/h1>'); | expect(await page.getInnerHtml(codeExample)).toContain('<h1>Tour of He roes</h1>'); | |||
}); | }); | |||
describe('scrolling to the top', () => { | describe('scrolling to the top', () => { | |||
it('should scroll to the top when navigating to another page', () => { | it('should scroll to the top when navigating to another page', async () => { | |||
page.navigateTo('guide/security'); | await page.navigateTo('guide/security'); | |||
page.scrollTo('bottom'); | await page.scrollTo('bottom'); | |||
expect(page.getScrollTop()).toBeGreaterThan(0); | expect(await page.getScrollTop()).toBeGreaterThan(0); | |||
// Navigate to Reference section, then check | // Navigate to Reference section, then check | |||
// Find the navigation item that has the text "api" | // Find the navigation item that has the text "api" | |||
page.click(page.getNavItem(/reference/i)); | await page.click(page.getNavItem(/reference/i)); | |||
page.click(page.getNavItem(/api/i)); | await page.click(page.getNavItem(/api/i)); | |||
expect(page.locationPath()).toBe('/api'); | expect(await page.locationPath()).toBe('/api'); | |||
expect(page.getScrollTop()).toBe(0); | expect(await page.getScrollTop()).toBe(0); | |||
}); | }); | |||
it('should scroll to the top when navigating to the same page', () => { | it('should scroll to the top when navigating to the same page', async () => | |||
page.navigateTo('guide/security'); | { | |||
await page.navigateTo('guide/security'); | ||||
page.scrollTo('bottom'); | await page.scrollTo('bottom'); | |||
expect(page.getScrollTop()).toBeGreaterThan(0); | expect(await page.getScrollTop()).toBeGreaterThan(0); | |||
page.click(page.getNavItem(/security/i)); | await page.click(page.getNavItem(/security/i)); | |||
expect(page.locationPath()).toBe('/guide/security'); | expect(await page.locationPath()).toBe('/guide/security'); | |||
expect(page.getScrollTop()).toBe(0); | expect(await page.getScrollTop()).toBe(0); | |||
}); | }); | |||
}); | }); | |||
describe('tutorial docs', () => { | describe('tutorial docs', () => { | |||
it('should not render a paragraph element inside the h1 element', () => { | it('should not render a paragraph element inside the h1 element', async () = | |||
page.navigateTo('tutorial/toh-pt1'); | > { | |||
expect(element(by.css('h1 p')).isPresent()).toBeFalsy(); | await page.navigateTo('tutorial/toh-pt1'); | |||
expect(await element(by.css('h1 p')).isPresent()).toBeFalsy(); | ||||
}); | }); | |||
}); | }); | |||
describe('contributors page', () => { | describe('contributors page', () => { | |||
const groupButtons = element(by.css('.group-buttons')).all(by.css('.filter-b utton')); | const groupButtons = element(by.css('.group-buttons')).all(by.css('.filter-b utton')); | |||
const contributors = element(by.css('.contributor-group')).all(by.css('aio-c ontributor')); | const contributors = element(by.css('.contributor-group')).all(by.css('aio-c ontributor')); | |||
beforeAll(() => page.navigateTo('about')); | beforeAll(() => page.navigateTo('about')); | |||
it('should have the expected groups', () => { | it('should have the expected groups', async () => { | |||
expect(groupButtons.count()).toBe(3); | expect(await groupButtons.count()).toBe(3); | |||
const texts = groupButtons.map<string>(btn => btn && btn.getText()); | const texts = await groupButtons.map<string>(btn => btn?.getText()); | |||
expect(texts).toEqual(['ANGULAR', 'COLLABORATORS', 'GDE']); | expect(texts).toEqual(['ANGULAR', 'COLLABORATORS', 'GDE']); | |||
}); | }); | |||
it('should have contributors listed in each group', () => { | it('should have contributors listed in each group', async () => { | |||
// WebDriver calls `scrollIntoView()` on the element to bring it into the visible area of the | // WebDriver calls `scrollIntoView()` on the element to bring it into the visible area of the | |||
// browser, before clicking it. By default, this aligns the top of the ele ment to the top of | // browser, before clicking it. By default, this aligns the top of the ele ment to the top of | |||
// the window. As a result, the element may end up behing the fixed top me nu, thus being | // the window. As a result, the element may end up behing the fixed top me nu, thus being | |||
// unclickable. To avoid this, we click the element directly using JavaScr ipt instead. | // unclickable. To avoid this, we click the element directly using JavaScr ipt instead. | |||
const clickButton = (elementFinder: ElementFinder) => elementFinder.getWeb | const clickButton = | |||
Element().then( | (elementFinder: ElementFinder) => browser.executeScript('arguments[0]. | |||
webElement => browser.executeScript('arguments[0].click()', webElement | click()', elementFinder); | |||
)); | ||||
const getContributorNames = | const getContributorNames = | |||
() => contributors.all(by.css('h3')).map<string>(c => c && c.getText() ); | () => contributors.all(by.css('h3')).map<string>(c => c?.getText()); | |||
const names1 = getContributorNames(); | const names1 = await getContributorNames(); | |||
expect(contributors.count()).toBeGreaterThan(1); | expect(await contributors.count()).toBeGreaterThan(1); | |||
expect(names1.length).toBeGreaterThan(1); | ||||
clickButton(groupButtons.get(1)); | ||||
const names2 = getContributorNames(); | await clickButton(groupButtons.get(1)); | |||
expect(contributors.count()).toBeGreaterThan(1); | const names2 = await getContributorNames(); | |||
expect(await contributors.count()).toBeGreaterThan(1); | ||||
expect(names2.length).toBeGreaterThan(1); | ||||
expect(names2).not.toEqual(names1); | expect(names2).not.toEqual(names1); | |||
clickButton(groupButtons.get(2)); | await clickButton(groupButtons.get(2)); | |||
const names3 = getContributorNames(); | const names3 = await getContributorNames(); | |||
expect(contributors.count()).toBeGreaterThan(1); | expect(await contributors.count()).toBeGreaterThan(1); | |||
expect(names2.length).toBeGreaterThan(1); | ||||
expect(names3).not.toEqual(names2); | expect(names3).not.toEqual(names2); | |||
expect(names3).not.toEqual(names1); | expect(names3).not.toEqual(names1); | |||
clickButton(groupButtons.get(0)); | await clickButton(groupButtons.get(0)); | |||
const names4 = getContributorNames(); | const names4 = await getContributorNames(); | |||
expect(contributors.count()).toBeGreaterThan(1); | expect(await contributors.count()).toBeGreaterThan(1); | |||
expect(names4.length).toBeGreaterThan(1); | ||||
expect(names4).not.toEqual(names3); | expect(names4).not.toEqual(names3); | |||
expect(names4).not.toEqual(names2); | expect(names4).not.toEqual(names2); | |||
expect(names4).toEqual(names1); | expect(names4).toEqual(names1); | |||
}); | }); | |||
}); | }); | |||
describe('google analytics', () => { | describe('google analytics', () => { | |||
it('should call ga with initial URL', done => { | it('should call ga with initial URL', async () => { | |||
let path: string; | await page.navigateTo('api'); | |||
page.navigateTo('api'); | ||||
page.locationPath() | const path = await page.locationPath(); | |||
.then(p => path = p) | const calls = await page.ga(); | |||
.then(() => page.ga()) | ||||
.then(calls => { | // The last call (length-1) will be the `send` command | |||
// The last call (length-1) will be the `send` command | // The second to last call (length-2) will be the command to `set` the pag | |||
// The second to last call (length-2) will be the command to `set` the | e url | |||
page url | expect(calls[calls.length - 2]).toEqual(['set', 'page', path]); | |||
expect(calls[calls.length - 2]).toEqual(['set', 'page', path]); | }); | |||
done(); | ||||
}); | it('should call ga with new URL on navigation', async () => { | |||
}); | await page.navigateTo(''); | |||
await page.click(page.getTopMenuLink('features')); | ||||
it('should call ga with new URL on navigation', done => { | ||||
let path: string; | const path = await page.locationPath(); | |||
page.navigateTo(''); | const calls = await page.ga(); | |||
page.click(page.getTopMenuLink('features')); | ||||
page.locationPath() | // The last call (length-1) will be the `send` command | |||
.then(p => path = p) | // The second to last call (length-2) will be the command to `set` the pag | |||
.then(() => page.ga()) | e url | |||
.then(calls => { | expect(calls[calls.length - 2]).toEqual(['set', 'page', path]); | |||
// The last call (length-1) will be the `send` command | ||||
// The second to last call (length-2) will be the command to `set` the | ||||
page url | ||||
expect(calls[calls.length - 2]).toEqual(['set', 'page', path]); | ||||
done(); | ||||
}); | ||||
}); | }); | |||
}); | }); | |||
describe('404 page', () => { | describe('404 page', () => { | |||
it('should add or remove the "noindex" meta tag depending upon the validity | it('should add or remove the "noindex" meta tag depending upon the validity | |||
of the page', () => { | of the page', async () => { | |||
page.navigateTo(''); | await page.navigateTo(''); | |||
expect(element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy(); | expect(await element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy | |||
(); | ||||
page.navigateTo('does/not/exist'); | await page.navigateTo('does/not/exist'); | |||
expect(element(by.css('meta[name="robots"][content="noindex"]')).isPresent | expect(await element(by.css('meta[name="robots"][content="noindex"]')).isP | |||
()).toBeTruthy(); | resent()).toBeTruthy(); | |||
page.click(page.getTopMenuLink('features')); | await page.click(page.getTopMenuLink('features')); | |||
expect(element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy(); | expect(await element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy | |||
(); | ||||
}); | }); | |||
it('should search the index for words found in the url', () => { | it('should search the index for words found in the url', async () => { | |||
page.navigateTo('http/router'); | await page.navigateTo('http/router'); | |||
const results = page.getSearchResults(); | const results = await page.getSearchResults(); | |||
expect(results).toContain('HttpRequest'); | expect(results).toContain('HttpRequest'); | |||
expect(results).toContain('Router'); | expect(results).toContain('Router'); | |||
}); | }); | |||
}); | }); | |||
describe('suggest edit link', () => { | describe('suggest edit link', () => { | |||
it('should be present on all docs pages', () => { | it('should be present on all docs pages', async () => { | |||
page.navigateTo('tutorial/toh-pt1'); | await page.navigateTo('tutorial/toh-pt1'); | |||
expect(page.ghLinks.count()).toEqual(1); | expect(await page.ghLinks.count()).toEqual(1); | |||
/* tslint:disable:max-line-length */ | /* tslint:disable:max-line-length */ | |||
expect(page.ghLinks.get(0).getAttribute('href')) | expect(await page.ghLinks.get(0).getAttribute('href')) | |||
.toMatch(/https:\/\/github\.com\/angular\/angular\/edit\/master\/aio\/co ntent\/tutorial\/toh-pt1\.md\?message=docs%3A%20describe%20your%20change\.\.\./) ; | .toMatch(/https:\/\/github\.com\/angular\/angular\/edit\/master\/aio\/co ntent\/tutorial\/toh-pt1\.md\?message=docs%3A%20describe%20your%20change\.\.\./) ; | |||
page.navigateTo('guide/http'); | await page.navigateTo('guide/http'); | |||
expect(page.ghLinks.count()).toEqual(1); | expect(await page.ghLinks.count()).toEqual(1); | |||
/* tslint:disable:max-line-length */ | /* tslint:disable:max-line-length */ | |||
expect(page.ghLinks.get(0).getAttribute('href')) | expect(await page.ghLinks.get(0).getAttribute('href')) | |||
.toMatch(/https:\/\/github\.com\/angular\/angular\/edit\/master\/aio\/co ntent\/guide\/http\.md\?message=docs%3A%20describe%20your%20change\.\.\./); | .toMatch(/https:\/\/github\.com\/angular\/angular\/edit\/master\/aio\/co ntent\/guide\/http\.md\?message=docs%3A%20describe%20your%20change\.\.\./); | |||
}); | }); | |||
it('should not be present on top level pages', () => { | it('should not be present on top level pages', async () => { | |||
page.navigateTo('features'); | await page.navigateTo('features'); | |||
expect(page.ghLinks.count()).toEqual(0); | expect(await page.ghLinks.count()).toEqual(0); | |||
}); | }); | |||
}); | }); | |||
}); | }); | |||
End of changes. 46 change blocks. | ||||
136 lines changed or deleted | 141 lines changed or added |