Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/1617 e2e coverage for scopes #1735

Merged
merged 36 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9352269
Add base write-scope-requests.test.js file.
eugene-manuilov Jun 30, 2020
0dcf5fe
Merge branch 'develop' of github.com:google/site-kit-wp into enhancem…
eugene-manuilov Jun 30, 2020
6fd042f
Merge branch 'develop' of github.com:google/site-kit-wp into enhancem…
eugene-manuilov Jul 1, 2020
f5990e8
Add check for a notice above the button that explains user will need …
eugene-manuilov Jul 1, 2020
1801ad5
Implement the first part of e2e to check creating ga account permissi…
eugene-manuilov Jul 1, 2020
221a4c6
Update request interseption to return correct ticket id and mock TOS …
eugene-manuilov Jul 2, 2020
c593d86
Rework the "creating an analytics account when not having scope yet" …
eugene-manuilov Jul 2, 2020
85d641d
Implement "creating an analytics property when not having the scope y…
eugene-manuilov Jul 2, 2020
3cbacbf
Fix too early lookup issue.
eugene-manuilov Jul 2, 2020
61a8015
Implement "creating an analytics view when not having scope yet" test.
eugene-manuilov Jul 2, 2020
ed64a9d
Merge remote-tracking branch 'origin/develop' into enhancement/1617-e…
eugene-manuilov Jul 3, 2020
b4148bb
Merge remote-tracking branch 'origin/develop' into enhancement/1617-e…
eugene-manuilov Jul 8, 2020
af0a740
Add view name field to the analytics setup form.
eugene-manuilov Jul 8, 2020
c763201
Fix default view name issue.
eugene-manuilov Jul 8, 2020
846cb33
Merge remote-tracking branch 'origin/develop' into enhancement/1617-e…
eugene-manuilov Jul 9, 2020
f7b0499
Merge remote-tracking branch 'origin/develop' into enhancement/1617-e…
eugene-manuilov Jul 9, 2020
067e8a9
Update e2e tests to properly check property and profile creation.
eugene-manuilov Jul 9, 2020
e38f24b
Merge remote-tracking branch 'origin/develop' into enhancement/1617-e…
eugene-manuilov Jul 10, 2020
3784da0
Address PR feedback.
eugene-manuilov Jul 10, 2020
76cc54b
Fix eslint issue.
eugene-manuilov Jul 10, 2020
f074876
Address PR feedback.
eugene-manuilov Jul 10, 2020
b143953
Update test name.
eugene-manuilov Jul 10, 2020
79a3307
Remove extra space at the end of match element string.
eugene-manuilov Jul 10, 2020
6760bec
Update test name.
eugene-manuilov Jul 10, 2020
307afb4
Update test name.
eugene-manuilov Jul 10, 2020
1a34b25
Remove unnecessary plugin.
eugene-manuilov Jul 10, 2020
691557f
Add back e2e-tests-site-verification-plugin plugin.
eugene-manuilov Jul 10, 2020
bbe0c08
Merge remote-tracking branch 'origin/develop' into enhancement/1617-e…
eugene-manuilov Jul 10, 2020
003a545
Remove e2e-tests-site-verification-plugin plugin activation.
eugene-manuilov Jul 10, 2020
6cf2405
Revert changes in the account-create.js script.
eugene-manuilov Jul 13, 2020
7b3e747
Merge branch 'develop' into enhancement/1617-e2e-coverage-for-scopes
aaemnnosttv Jul 14, 2020
56cd7de
Downgrade focus-trap-react to v6.
aaemnnosttv Jul 14, 2020
356303d
Update tests to ensure original action is automatically invoked on re…
aaemnnosttv Jul 14, 2020
459ddd5
Merge branch 'develop' into enhancement/1617-e2e-coverage-for-scopes
aaemnnosttv Jul 14, 2020
1a04c43
Merge branch 'develop' into enhancement/1617-e2e-coverage-for-scopes
aaemnnosttv Jul 14, 2020
273b7a0
Merge branch 'develop' into enhancement/1617-e2e-coverage-for-scopes
aaemnnosttv Jul 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions jest-puppeteer.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ module.exports = {
args: [
// https://peter.sh/experiments/chromium-command-line-switches/
...coreLaunchArgs,
'--disable-gpu',
'--no-sandbox',
'--disable-setuid-sandbox',
eugene-manuilov marked this conversation as resolved.
Show resolved Hide resolved
'--disable-dev-shm-usage',
],
},
Expand Down
46 changes: 31 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"classnames": "^2.2.6",
"dompurify": "^2.0.12",
"element-closest": "^3.0.2",
"focus-trap-react": "^7.0.1",
"focus-trap-react": "^6.0.0",
"formdata-polyfill": "^3.0.20",
"husky": "^4.2.5",
"intl": "^1.2.5",
Expand Down
248 changes: 248 additions & 0 deletions tests/e2e/specs/modules/analytics/write-scope-requests.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/**
* Analytics write scope requests tests.
*
* Site Kit by Google, Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* WordPress dependencies
*/
import { activatePlugin, createURL, visitAdminPage } from '@wordpress/e2e-test-utils';

/**
* Internal dependencies
*/
import {
deactivateUtilityPlugins,
resetSiteKit,
useRequestInterception,
setupSiteKit,
} from '../../../utils';

describe( 'Analytics write scope requests', () => {
let scope;
// These variables are used to determine whether or not we need to intercept requests to the server. By default the first request
// won't be intercepted to reach the server and to trigger the insufficient scopes error on the server. The following requests will
// be intercepted and mocked to immediately return fake data to emulate property/profile creation.
let interceptCreatePropertyRequest;
let interceptCreateProfileRequest;
eugene-manuilov marked this conversation as resolved.
Show resolved Hide resolved

beforeAll( async () => {
await page.setRequestInterception( true );
useRequestInterception( ( request ) => {
if ( request.url().startsWith( 'https://sitekit.withgoogle.com/o/oauth2/auth' ) ) {
request.respond( {
status: 302,
headers: {
location: createURL( '/wp-admin/index.php', `oauth2callback=1&code=valid-test-code&scope=${ scope }` ),
},
} );
} else if ( request.url().match( 'analytics/data/create-account-ticket' ) ) {
request.respond( {
status: 200,
body: JSON.stringify( { id: `${ Math.ceil( 1000 * Math.random() ) }` } ),
} );
} else if ( request.url().match( 'analytics/data/create-property' ) ) {
if ( interceptCreatePropertyRequest ) {
request.respond( {
status: 200,
body: JSON.stringify( {
accountId: '100',
id: 'UA-100-1',
internalWebPropertyId: '200',
kind: 'analytics#webproperty',
level: 'STANDARD',
name: 'Test Property X',
websiteUrl: '/wp-admin/',
permissions: {
effective: [
'READ_AND_ANALYZE',
],
},
} ),
} );
} else {
request.continue();
interceptCreatePropertyRequest = true;
}
} else if ( request.url().match( 'analytics/data/create-profile' ) ) {
if ( interceptCreateProfileRequest ) {
request.respond( {
status: 200,
body: JSON.stringify( {
id: '300',
accountId: '100',
webPropertyId: 'UA-100-1',
internalWebPropertyId: '200',
kind: 'analytics#profile',
level: 'STANDARD',
name: 'Test Profile X',
type: 'WEB',
websiteUrl: '/wp-admin/',
permissions: {
effective: [
'READ_AND_ANALYZE',
],
},
} ),
} );
} else {
request.continue();
interceptCreateProfileRequest = true;
}
} else if ( request.url().match( '/wp-json/google-site-kit/v1/data/' ) ) {
request.respond( { status: 200 } );
} else if ( request.url().match( `//analytics.google.com/analytics/web/` ) ) {
request.respond( { status: 200 } );
} else {
request.continue();
}
} );
} );

beforeEach( async () => {
scope = 'https://www.googleapis.com/auth/analytics.provision';
interceptCreatePropertyRequest = false;
interceptCreateProfileRequest = false;

await activatePlugin( 'e2e-tests-oauth-callback-plugin' );
await setupSiteKit();
} );

afterEach( async () => {
await deactivateUtilityPlugins();
await resetSiteKit();
} );

it( 'prompts for additional permissions during a new Analytics account creation if the user has not granted the Analytics provisioning scope', async () => {
await activatePlugin( 'e2e-tests-module-setup-analytics-api-mock-no-account' );

// Go to the analytics setup page.
await visitAdminPage( 'admin.php', 'page=googlesitekit-settings' );
await page.waitForSelector( '.mdc-tab-bar' );
await expect( page ).toClick( '.mdc-tab', { text: /connect more services/i } );
await page.waitForSelector( '.googlesitekit-settings-connect-module--analytics' );
await expect( page ).toClick( '.googlesitekit-cta-link', { text: /set up analytics/i } );
await page.waitForSelector( '.googlesitekit-setup-module--analytics' );
await page.waitForSelector( '.googlesitekit-setup-module__inputs' );

// The user sees a notice above the button that explains they will need to grant additional permissions.
await expect( page ).toMatchElement( 'p', { text: /You will need to give Site Kit permission to create an Analytics account/i } );

// Upon clicking the button, they're redirected to OAuth (should be mocked).
await Promise.all( [
page.waitForNavigation(), // User is sent directly to OAuth.
expect( page ).toClick( '.mdc-button', { text: /create account/i } ),
] );

// When returning, their original action is automatically invoked, without requiring them to click the button again.
await page.waitForRequest( ( req ) => req.url().match( 'analytics/data/create-account-ticket' ) );

// They should be redirected to the Analytics TOS.
await page.waitForRequest( ( req ) => req.url().match( 'analytics.google.com/analytics/web' ) );
} );

it( 'prompts for additional permissions during a new Analytics property creation if the user has not granted the Analytics edit scope', async () => {
scope = 'https://www.googleapis.com/auth/analytics.edit';
interceptCreateProfileRequest = true;

await activatePlugin( 'e2e-tests-module-setup-analytics-api-mock' );

// Go to the analytics setup page.
await visitAdminPage( 'admin.php', 'page=googlesitekit-settings' );
await page.waitForSelector( '.mdc-tab-bar' );
await expect( page ).toClick( '.mdc-tab', { text: /connect more services/i } );
await page.waitForSelector( '.googlesitekit-settings-connect-module--analytics' );
await expect( page ).toClick( '.googlesitekit-cta-link', { text: /set up analytics/i } );
await page.waitForSelector( '.googlesitekit-setup-module--analytics' );
await page.waitForSelector( '.googlesitekit-setup-module__inputs' );

// Select "Test Account A" account.
await expect( page ).toClick( '.googlesitekit-analytics__select-account' );
await expect( page ).toClick( '.mdc-menu-surface--open li', { text: /test account a/i } );

// Select "Set up a new property" option.
await expect( page ).toClick( '.googlesitekit-analytics__select-property' );
await expect( page ).toClick( '.mdc-menu-surface--open li', { text: /set up a new property/i } );

// Click on confirm changes button and wait for permissions modal dialog.
await expect( page ).toClick( '.mdc-button', { text: /configure analytics/i } );
await page.waitForSelector( '.mdc-dialog__container' );

// Click on proceed button and wait for oauth request.
await Promise.all( [
expect( page ).toClick( '.mdc-dialog__actions .mdc-button', { text: /proceed/i } ),
page.waitForRequest( ( req ) => req.url().match( 'sitekit.withgoogle.com/o/oauth2/auth' ) ),
] );

// When returning, their original action is automatically invoked, without requiring them to click the button again.
await page.waitForRequest( ( req ) => req.url().match( 'analytics/data/create-property' ) );
await page.waitForRequest( ( req ) => req.url().match( 'analytics/data/create-profile' ) );

// They should end up on the dashboard.
await Promise.all( [
page.waitForNavigation(),
page.waitForSelector( '.googlesitekit-publisher-win__title' ),
] );
await expect( page ).toMatchElement( '.googlesitekit-publisher-win__title', { text: /Congrats on completing the setup for Analytics!/i } );
} );

it( 'prompts for additional permissions during a new Analytics profile creation if the user has not granted the Analytics edit scope', async () => {
scope = 'https://www.googleapis.com/auth/analytics.edit';

await activatePlugin( 'e2e-tests-module-setup-analytics-api-mock' );

// Go to the analytics setup page.
await visitAdminPage( 'admin.php', 'page=googlesitekit-settings' );
await page.waitForSelector( '.mdc-tab-bar' );
await expect( page ).toClick( '.mdc-tab', { text: /connect more services/i } );
await page.waitForSelector( '.googlesitekit-settings-connect-module--analytics' );
await expect( page ).toClick( '.googlesitekit-cta-link', { text: /set up analytics/i } );
await page.waitForSelector( '.googlesitekit-setup-module--analytics' );
await page.waitForSelector( '.googlesitekit-setup-module__inputs' );

// Select "Test Account A" account.
await expect( page ).toClick( '.googlesitekit-analytics__select-account' );
await expect( page ).toClick( '.mdc-menu-surface--open li', { text: /test account a/i } );

// Select "Test Property X" property.
await expect( page ).toClick( '.googlesitekit-analytics__select-property' );
await expect( page ).toClick( '.mdc-menu-surface--open li', { text: /test property x/i } );

// Select "Set up a new view" option.
await expect( page ).toClick( '.googlesitekit-analytics__select-profile' );
await expect( page ).toClick( '.mdc-menu-surface--open li', { text: /set up a new view/i } );

// Click on confirm changes button and wait for permissions modal dialog.
await expect( page ).toClick( '.mdc-button', { text: /configure analytics/i } );
await page.waitForSelector( '.mdc-dialog__container' );

// Click on proceed button and wait for oauth request.
await Promise.all( [
expect( page ).toClick( '.mdc-dialog__actions .mdc-button', { text: /proceed/i } ),
page.waitForRequest( ( req ) => req.url().match( 'sitekit.withgoogle.com/o/oauth2/auth' ) ),
] );

// When returning, their original action is automatically invoked, without requiring them to click the button again.
await page.waitForRequest( ( req ) => req.url().match( 'analytics/data/create-profile' ) );

// They should end up on the dashboard.
await Promise.all( [
page.waitForNavigation(),
page.waitForSelector( '.googlesitekit-publisher-win__title' ),
] );
await expect( page ).toMatchElement( '.googlesitekit-publisher-win__title', { text: /Congrats on completing the setup for Analytics!/i } );
} );
} );