Skip to content

Commit

Permalink
new_audit: inputs-can-be-pasted-into
Browse files Browse the repository at this point in the history
  • Loading branch information
connorjclark committed Dec 13, 2022
1 parent 80709e6 commit 93b3ff7
Show file tree
Hide file tree
Showing 66 changed files with 890,527 additions and 705 deletions.
10 changes: 5 additions & 5 deletions cli/test/fixtures/dobetterweb/dbw_tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ <h2>Do better web tester page</h2>
<a href="mailto:inbox@email.com" target="_blank"></a>
</template>

<template id="password-inputs-can-be-pasted-into">
<template id="inputs-can-be-pasted-into">
<!-- FAIL - calls preventDefault on event -->
<input type="password" onpaste="event.preventDefault();" />
<!-- PASS -->
Expand Down Expand Up @@ -361,8 +361,8 @@ <h2>Do better web tester page</h2>
stampTemplate('noopener-links-tmpl', document.body);
}

function passwordInputsCanBePastedIntoTest() {
stampTemplate('password-inputs-can-be-pasted-into', document.body);
function inputsCanBePastedIntoTest() {
stampTemplate('inputs-can-be-pasted-into', document.body);
}


Expand Down Expand Up @@ -405,7 +405,7 @@ <h2>Do better web tester page</h2>
noRelOpenLinksTest();
// oldCSSFlexboxTest();
deprecationsTest();
passwordInputsCanBePastedIntoTest();
inputsCanBePastedIntoTest();
isOnHttps();
noUnloadListenersTest();
} else {
Expand Down Expand Up @@ -440,7 +440,7 @@ <h2>Do better web tester page</h2>
deprecationsTest();
}
if (params.has('passwordinputs')) {
passwordInputsCanBePastedIntoTest();
inputsCanBePastedIntoTest();
}
if (params.has('isonhttps')) {
isOnHttps();
Expand Down
2 changes: 1 addition & 1 deletion cli/test/smokehouse/test-definitions/dobetterweb.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ const expectations = {
],
},
},
'password-inputs-can-be-pasted-into': {
'inputs-can-be-pasted-into': {
score: 0,
details: {
items: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const expectations = {
'render-blocking-resources': {
score: 1,
},
'password-inputs-can-be-pasted-into': {
'inputs-can-be-pasted-into': {
score: 1,
},
'service-worker': {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @license Copyright 2016 The Lighthouse Authors. All Rights Reserved.
* @license Copyright 2022 The Lighthouse Authors. All Rights Reserved.
* 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 http://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.
*/
Expand All @@ -8,13 +8,14 @@ import {Audit} from '../audit.js';
import * as i18n from '../../lib/i18n/i18n.js';

const UIStrings = {
/** Title of a Lighthouse audit that provides detail on the ability to paste into password fields. This descriptive title is shown to users when the page allows pasting of content into password fields. */
title: 'Allows users to paste into password fields',
/** Title of a Lighthouse audit that provides detail on the ability to paste into password fields. This descriptive title is shown to users when the page does not allow pasting of content into password fields. */
failureTitle: 'Prevents users to paste into password fields',
/** Description of a Lighthouse audit that tells the user why they should allow pasting of content into password fields. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
description: 'Preventing password pasting undermines good security policy. ' +
'[Learn more about user-friendly password fields](https://developer.chrome.com/docs/lighthouse/best-practices/password-inputs-can-be-pasted-into/).',
/** Title of a Lighthouse audit that provides detail on the ability to paste into input fields. This descriptive title is shown to users when the page allows pasting of content into input fields. */
title: 'Allows users to paste into input fields',
/** Title of a Lighthouse audit that provides detail on the ability to paste into input fields. This descriptive title is shown to users when the page does not allow pasting of content into input fields. */
failureTitle: 'Prevents users from pasting into input fields',
/** Description of a Lighthouse audit that tells the user why they should allow pasting of content into input fields. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Preventing input pasting is a UX anti-pattern, ' +
'and undermines good security policy. ' +
'[Learn more about user-friendly input fields](https://developer.chrome.com/docs/lighthouse/best-practices/password-inputs-can-be-pasted-into/).',
};

const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
Expand All @@ -25,11 +26,11 @@ class PasswordInputsCanBePastedIntoAudit extends Audit {
*/
static get meta() {
return {
id: 'password-inputs-can-be-pasted-into',
id: 'inputs-can-be-pasted-into',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['PasswordInputsWithPreventedPaste'],
requiredArtifacts: ['Inputs'],
};
}

Expand All @@ -38,14 +39,15 @@ class PasswordInputsCanBePastedIntoAudit extends Audit {
* @return {LH.Audit.Product}
*/
static audit(artifacts) {
const passwordInputsWithPreventedPaste = artifacts.PasswordInputsWithPreventedPaste;
const inputsWithPreventsPaste = artifacts.Inputs.inputs.filter(input => input.preventsPaste);

/** @type {LH.Audit.Details.Table['items']} */
const items = [];

passwordInputsWithPreventedPaste.forEach(input => {
inputsWithPreventsPaste.forEach(input => {
items.push({
node: Audit.makeNodeItem(input.node),
type: input.type,
});
});

Expand All @@ -55,7 +57,7 @@ class PasswordInputsCanBePastedIntoAudit extends Audit {
];

return {
score: Number(passwordInputsWithPreventedPaste.length === 0),
score: Number(inputsWithPreventsPaste.length === 0),
details: Audit.makeTableDetails(headings, items),
};
}
Expand Down
6 changes: 2 additions & 4 deletions core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ const artifacts = {
MetaElements: '',
NetworkUserAgent: '',
OptimizedImages: '',
PasswordInputsWithPreventedPaste: '',
ResponseCompression: '',
RobotsTxt: '',
ServiceWorker: '',
Expand Down Expand Up @@ -199,7 +198,6 @@ const defaultConfig = {
{id: artifacts.MetaElements, gatherer: 'meta-elements'},
{id: artifacts.NetworkUserAgent, gatherer: 'network-user-agent'},
{id: artifacts.OptimizedImages, gatherer: 'dobetterweb/optimized-images'},
{id: artifacts.PasswordInputsWithPreventedPaste, gatherer: 'dobetterweb/password-inputs-with-prevented-paste'},
{id: artifacts.ResponseCompression, gatherer: 'dobetterweb/response-compression'},
{id: artifacts.RobotsTxt, gatherer: 'seo/robots-txt'},
{id: artifacts.ServiceWorker, gatherer: 'service-worker'},
Expand Down Expand Up @@ -358,7 +356,7 @@ const defaultConfig = {
'dobetterweb/no-document-write',
'dobetterweb/js-libraries',
'dobetterweb/notification-on-start',
'dobetterweb/password-inputs-can-be-pasted-into',
'dobetterweb/inputs-can-be-pasted-into',
'dobetterweb/uses-http2',
'dobetterweb/uses-passive-event-listeners',
'seo/meta-description',
Expand Down Expand Up @@ -610,7 +608,7 @@ const defaultConfig = {
{id: 'notification-on-start', weight: 1, group: 'best-practices-trust-safety'},
{id: 'csp-xss', weight: 0, group: 'best-practices-trust-safety'},
// User Experience
{id: 'password-inputs-can-be-pasted-into', weight: 1, group: 'best-practices-ux'},
{id: 'inputs-can-be-pasted-into', weight: 1, group: 'best-practices-ux'},
{id: 'image-aspect-ratio', weight: 1, group: 'best-practices-ux'},
{id: 'image-size-responsive', weight: 1, group: 'best-practices-ux'},
{id: 'preload-fonts', weight: 1, group: 'best-practices-ux'},
Expand Down

This file was deleted.

6 changes: 6 additions & 0 deletions core/gather/gatherers/inputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ function collectElements() {
return [...labelElToArtifact.keys()].indexOf(labelEl);
});

let preventsPaste;
if (!inputEl.readOnly) {
preventsPaste = !inputEl.dispatchEvent(new ClipboardEvent('paste', {cancelable: true}));
}

inputArtifacts.push({
parentFormIndex,
labelIndices,
Expand All @@ -74,6 +79,7 @@ function collectElements() {
// Requires `--enable-features=AutofillShowTypePredictions`.
prediction: inputEl.getAttribute('autofill-prediction'),
},
preventsPaste,
// @ts-expect-error - getNodeDetails put into scope via stringification
node: getNodeDetails(inputEl),
});
Expand Down
36 changes: 36 additions & 0 deletions core/test/audits/dobetterweb/inputs-can-be-pasted-into-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @license Copyright 2022 The Lighthouse Authors. All Rights Reserved.
* 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 http://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.
*/

import {strict as assert} from 'assert';

import InputsCanBePastedIntoAudit from '../../../audits/dobetterweb/inputs-can-be-pasted-into.js';

describe('Inputs can be pasted into', () => {
it('passes when there are no inputs preventing paste', () => {
const auditResult = InputsCanBePastedIntoAudit.audit({
Inputs: {
inputs: [],
},
});
assert.equal(auditResult.score, 1);
assert.equal(auditResult.details.items.length, 0);
});

it('fails when there are inputs preventing paste', () => {
const auditResult = InputsCanBePastedIntoAudit.audit({
Inputs: {
inputs: [
{node: {snippet: 'bad'}, preventsPaste: true},
{node: {snippet: ''}, preventsPaste: false},
{node: {snippet: ''}},
],
},
});
assert.equal(auditResult.score, 0);
assert.equal(auditResult.details.items.length, 1);
assert.equal(auditResult.details.items[0].node.snippet, 'bad');
});
});

This file was deleted.

Loading

0 comments on commit 93b3ff7

Please sign in to comment.