blob: 2541b8eee854cef67d79bc00f34d7cf34570f311 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Host from '../../core/host/host.js';
import * as Platform from '../../core/platform/platform.js';
import type * as Root from '../../core/root/root.js';
import {createTarget, updateHostConfig} from '../../testing/EnvironmentHelpers.js';
import {describeWithMockConnection} from '../../testing/MockConnection.js';
import * as UIHelpers from './helpers.js';
const {urlString} = Platform.DevToolsPath;
describe('openInNewTab', () => {
const {openInNewTab} = UIHelpers;
const {InspectorFrontendHostInstance} = Host.InspectorFrontendHost;
it('throws a TypeError if the URL is invalid', () => {
assert.throws(() => openInNewTab('ThisIsNotAValidURL'), TypeError);
});
it('opens URLs via host bindings', () => {
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab('https://www.google.com/');
sinon.assert.callCount(stub, 1);
assert.deepEqual(stub.args[0], ['https://www.google.com/']);
});
it('opens URLs and appends slash if needed', () => {
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab('https://www.google.com');
sinon.assert.callCount(stub, 1);
assert.deepEqual(stub.args[0], ['https://www.google.com/']);
});
it('doesn\'t override existing `utm_source` search parameters', () => {
const URLs = [
'http://developer.chrome.com/docs/devtools/workspaces/?utm_source=unittests',
'http://developers.google.com/learn/?utm_source=unittests',
'http://web.dev/?utm_source=unittests',
'http://www.google.com/?utm_source=unittests',
'https://developer.chrome.com/docs/devtools/?utm_source=unittests',
'https://developers.google.com/community/?utm_source=unittests',
'https://www.google.com/?utm_source=unittests',
'https://web.dev/baseline/?utm_source=unittests',
];
for (const url of URLs) {
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab(url);
sinon.assert.calledOnceWithExactly(stub, urlString`${url}`);
stub.restore();
}
});
it('adds `utm_source` search parameter to Google documentation set links', () => {
const URLs = [
'http://developer.chrome.com/docs/devtools/workspaces/',
'http://developers.google.com/learn/',
'http://web.dev/',
'https://developer.chrome.com/docs/devtools/',
'https://developers.google.com/community/',
'https://web.dev/baseline/',
];
for (const url of URLs) {
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab(url);
sinon.assert.calledOnce(stub);
assert.strictEqual(new URL(stub.args[0][0]).searchParams.get('utm_source'), 'devtools');
stub.restore();
}
});
it('adds `utm_campaign` search parameter to Google documentation set links', () => {
const CHANNELS: Array<typeof Root.Runtime.hostConfig.channel> = [
'stable',
'beta',
'dev',
'canary',
];
const URLs = [
'http://developer.chrome.com/docs/devtools/workspaces/',
'http://developers.google.com/learn/',
'http://web.dev/',
'https://developer.chrome.com/docs/devtools/',
'https://developers.google.com/community/',
'https://web.dev/baseline/',
];
for (const channel of CHANNELS) {
updateHostConfig({channel});
for (const url of URLs) {
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab(url);
sinon.assert.calledOnce(stub);
assert.strictEqual(new URL(stub.args[0][0]).searchParams.get('utm_campaign'), channel);
stub.restore();
}
}
});
it('correctly preserves anchors', () => {
updateHostConfig({channel: 'stable'});
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab('https://developer.chrome.com/docs/devtools/settings/ignore-list/#skip-third-party');
sinon.assert.calledOnce(stub);
const url = new URL(stub.args[0][0]);
assert.strictEqual(url.hash, '#skip-third-party');
assert.strictEqual(url.searchParams.get('utm_campaign'), 'stable');
assert.strictEqual(url.searchParams.get('utm_source'), 'devtools');
});
it('correctly preserves other search params', () => {
updateHostConfig({channel: 'stable'});
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab('http://web.dev/route?foo=bar&baz=devtools');
sinon.assert.calledOnce(stub);
const url = new URL(stub.args[0][0]);
assert.strictEqual(url.searchParams.get('baz'), 'devtools');
assert.strictEqual(url.searchParams.get('foo'), 'bar');
assert.strictEqual(url.searchParams.get('utm_campaign'), 'stable');
assert.strictEqual(url.searchParams.get('utm_source'), 'devtools');
});
it('does nothing for javascript: urls', () => {
const stub = sinon.stub(InspectorFrontendHostInstance, 'openInNewTab');
openInNewTab('javascript:alert("Hey")');
sinon.assert.callCount(stub, 0);
});
describeWithMockConnection('chrome:// link', () => {
it('call the correct API for chrome:// links', async () => {
const target = createTarget();
const spy = sinon.spy(target.targetAgent(), 'invoke_createTarget');
openInNewTab('chrome://settings');
sinon.assert.calledOnce(spy);
assert.deepEqual(spy.firstCall.firstArg, {url: 'chrome://settings/'});
});
});
});