Coder Social home page Coder Social logo

form-troubleshooter's Introduction

Form troubleshooter

A Chrome extension to find and fix common form problems.

Screenshot of Form troubleshooter extension popup, running on form-problems.glitch.me page, Recommendations tab selected

Screenshot of Form troubleshooter extension popup, running on form-problems.glitch.me page, Common mistakes tab selected

Screenshot of Form troubleshooter extension popup, running on form-problems.glitch.me page, Form details tab selected

Installation

This extension is be available from the Chrome Web Store.

You can also download the source code for the extension and build and install it locally.

Build from source

You will need Node.js 12 or later to build the extension.

  1. Download the code or clone the repo:

    git clone [email protected]:GoogleChromeLabs/form-troubleshooter.git

  2. Install dependencies: npm install
  3. Build the extension: npm run build

Install the extension locally

  1. In Chrome, navigate to chrome://extensions

    Screenshot of the chrome://extensions page

  2. Enable Developer mode

  3. Click the Load unpacked button and select the extension's folder:

    • If you downloaded form-troubleshooter-extension.zip, the extension's folder will be the location of the extracted folder.
    • If you built the extension from source, the extension's folder will be the build/ folder of the repository.
  4. You can pin the extension so its icon is always visible: from the Chrome Extensions menu, select Form Troubleshooter

    Screenshot of the Chrome Extensions menu

Usage

Visit a page you want to check, then click the extension icon. The extension retrieves and audits form elements and attributes every time the icon is clicked.

The extension popup has three sections:

  • Recommendations
  • Common mistakes
  • Form details

Save as HTML saves the report as a local HTML file.

You can try out the extension on the test page form-problems.glitch.me.

Development

To develop and test the extension locally, first follow the steps to build from source.

Local web server

Run the local web server with Hot Module Reloading (HMR):

npm run dev

Open http://localhost:8080/.

Note that developing in this mode requires you to bring your own form data. This can be achieved by referencing one of the existing data files in the test-data folder using the data query string parameter:

Or by loading a saved form file from the more menu in the top right of the popup.

Running tests

# one off test run
npm run test

# continuously watch for changes
npm run test:watch

Linting

Before contributing any code, make sure that code has been linted.

npm run lint

# reformat files automatically
npm run pretty

Caveats

  • The extension is designed to be used as a tool, not to confirm whether code is 'right' or 'wrong'. Form usage is often complex (especially for high-traffic sites) so it's difficult to provide form code validation that is appropriate across a variety of sites.
  • Some errors found by the extension may represent known problems, or be triggered by 'incorrect' code that is justified for reasons outside the scope of the extension. In particular, many high-traffic sites use form code in a variety of ways to function at scale and integrate with legacy and third-party systems. The same code may not be appropriate for smaller-scale sites.

However, please provide feedback or file a bug for audit results that appear to be incorrect.

How it works

The extension checks the current page for form and form field elements each time it's opened.

  1. The extension icon is clicked to open popup.html.
  2. popup.js sends a message to content-script.js that the popup has opened (popup opened).
  3. content-script.js traverses the DOM including the shadow DOM and iframes.
  4. content-script.js stores a DOM representation using chrome.storage which will be used by content-script.js.
  5. content-script.js sends a message via background.js that the DOM has been inspected (dom inspected).
  6. content-script.js stores form data using chrome.storage.
  7. content-script.js sends a message that element data has been stored (stored element data).
  8. On receiving the message, popup.js gets the data from chrome.storage.
  9. popup.js runs the audits defined in audits.js, to check the form elements and attributes in the page.
  10. popup.js displays an overview of form and form field data in popup.html.
  11. popup.js displays results of the audits in popup.html.

Feedback and feature requests

Feedback and audit suggestions welcome!

TODO

  • Link to and/or highlight problematic elements.
    • Link to items in the regular DOM.
    • Link to items in shadow DOM.
    • Link to items in iframes.
  • Move code for displaying audit results out of audits.js.
  • Move constants to external file.
  • Check for forms (or other elements) that don't have a closing tag.
  • Check for invalid type attribute values, for example <input type="check">.
  • Suggest alternatives to invalid attribute names, e.g. for autcomplete.

This is not a Google product.

form-troubleshooter's People

Contributors

release-please[bot] avatar samdutton avatar sanjoyghosh avatar socsieng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

form-troubleshooter's Issues

Strictness of invalid/unrecognized input attributes

I ran the extension against https://payments-react-store.web.app/checkout with chrome://flags/#show-autofill-type-predictions enabled and received the following:

image

Developers who are building/testing forms may have this flag enabled. Should autofill-information and autofill-prediction be added to the allowed list of attributes?

Also, what is the expectation around reporting issues and their severity? Should warnings be actionable?

Review audits and recommendations

Using the results of existing audits, review the validity of each of finding, including:

  • Severity (warning versus error)
  • Score/weighting
  • Wording
  • Suggestions/proposed actions

Identify any new audits that may be required.

Add suggestions for when a label's input cannot be found by id

Describe the solution you'd like A clear and concise description of what you want to happen.

Create a list of possible form field ids and use them as a potential list of suggestion for labels without a matching for field. Add a suggestion if it exists.

Example: There are no form fields with id="xxy", did you mean xxx?

image

Add set-up / local dev instructions

A quick section in the README to go to chrome://extensions, enable "Developer Mode", and then "Load unpacked" at the top-level directory would help.

Should we have special treatment for recaptcha to reduce overall noise?

The following has come up often and looks to be related to recaptcha. Should we add exempt this type of field from the audits?

Example for: https://www.ikea.com/gb/en/profile/signup/

Help your users using alternate input methods complete this form by ensuring each field is correctly labeled

Found input fields without a corresponding label:

  • <textarea id="g-recaptcha-response-100000" name="g-recaptcha-response" class="g-recaptcha-response" ...>
    • There are no labels that reference for="g-recaptcha-response-100000"

Add a score indicating how well the form follows guidance

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem
is. For example: I'm always frustrated when [...]

Include a score in the extension popup so that users can quickly assess how well their forms adhere to guidance and determine what (if any) action should be taken to remediate.

This score may be more useful for non-developers to take back to their development teams.

Describe the solution you'd like A clear and concise description of what you want to happen.

Add a score that summarizes the audit findings. Possibly something like an A to F scale, or 0 to 100% score. Ideally this would be consistent with how browsers evaluate Autofill confidence.

Example: https://www.figma.com/file/8aClB2ZylfcCqy0OhWn5GS/Form-troubleshooter-proposal

image

Describe alternatives you've considered A clear and concise description of any alternative solutions or features
you've considered.

None

Additional context Add any other context or screenshots about the feature request here.

None

Audit does not recognize billing autocomplete fields

Audit does not correctly recognize billing autocomplete fields according to html.spec.whatwg.org.

Resullt

Autocomplete values must be valid.
Found form field(s) with invalid autocomplete values:

  • <input autocomplete="billing address-line1" class="CheckoutInput Input Input--empty" id="billingAddressLine1" name="billingAddressLine1" placeholder="Address">
  • <input autocomplete="billing address-line2" class="CheckoutInput HiddenInput Input Input--empty" id="billingAddressLine2" name="billingAddressLine2" placeholder="Address line 2">
  • <input autocomplete="billing address-level2" class="CheckoutInput HiddenInput Input Input--empty" id="billingLocality" name="billingLocality" placeholder="City">
  • <input autocomplete="billing postal-code" class="CheckoutInput CheckoutInput--tabularnums HiddenInput Input Input--empty" id="billingPostalCode" name="billingPostalCode" placeholder="ZIP">
  • <select autocomplete="billing country" class="Select-source" id="billingCountry" name="billingCountry">
  • <select autocomplete="billing address-level1" class="Select-source Select-source--empty HiddenInput" id="billingAdministrativeArea" name="billingAdministrativeArea">

Steps to reproduce

  1. Visit: https://apple-pay-demo-c907a.firebaseapp.com/
  2. Click on Buy Now
  3. Run audit

Allow popup window to be moved

As a developer,
I want to be able to move and reposition the popup window
So that I can identify and highlight fields that may be obscured by the popup in its default position.

Not sure if this is possible, but would be nice if the feature was supported.

Add support for input/label detection using aria-labelledby attribute

Input fields should check aria-labelledby attribute to determine if an input field is labelled correctly and if a label is associated with an input field.

Example HTML fragment:

<label id="sizeLabel">Size</label>
<select id="sizeSelect" aria-labelledby="sizeLabel">
  <option value="XS">XS</option>
  <option value="S">S</option>
  <option value="M" selected="">M</option>
  <option value="L">L</option>
  <option value="XL">XL</option>
</select>

Form validation doesn't correctly take autocomplete "shipping tel" into account

The following was from a Shopify store's checkout page:

Autocomplete values must be valid.
Found form field(s) with invalid autocomplete values:

  • <input autocomplete="shipping tel" class="visually-hidden" name="checkout[shipping_address][phone]">
  • <input autocomplete="shipping tel" class="field__input field__input--numeric" id="checkout_shipping_address_phone" name="checkout[shipping_address][phone]" placeholder="Phone (optional)">

image

Expected the form and the telephone number field to be valid but was actually flagged as an error.

Move audit related logic out of content-script.js

content-script.js currently contains some audit related logic. Specifically, determining which attributes are/aren't invalid (invalidAttributes and invalidLabelDescendants).

Proposal:

Instead of checking for invalid attributes in content-script.js, add all relevant attributes and check for validity in audit.js. This will make it easier to also apply fuzzy attribute matches and provide alternate suggestions.

Include suggestion for autocomplete value audit

When an appropriate suggestion exists, include the details in the audit.

Example: https://www.just-eat.co.uk/account/register?returnUrl=%2F

Increase conversions by including autocomplete attributes

Found a form field with no autocomplete attribute, even though an appropriate value is available:

  • <input id="formField-email" type="email" placeholder=" " name="email" class="FormField_c-formField-input_14HCA FormField_c-formField-input--focus_EJdm1" ...>

image

Issue trying to highlight a form element with invalid id

https://www.wayfair.com/shop-the-look/slp/-wayfair-catalog-photo-id458852

Problematic id is sf-ui-header::top-nav.

Uncaught (in promise) DOMException: Failed to execute 'querySelector' on 'Document': 'html > body > div#doc3 > div#sf-ui-header::top-nav > header#store_nav > div:nth-of-type(2) > nav > div:nth-of-type(2) > form > div > div:nth-of-type(1) > div > div > div > label' is not a valid selector.
    at getRectangleBySelector (chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/lib/content-script.js:322:33)
    at highlightElements (chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/lib/content-script.js:306:24)
    at chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/lib/content-script.js:273:13

Some more context: https://stackoverflow.com/a/449000/12031739

Should autocomplete="off" be treated as a warning?

Related to #2 around severity and whether or not warnings should be actionable.

Warning from a Shopify store's checkout page:

Form fields should not use autocomplete="off".
Found form field(s) with autocomplete="off":

  • <input autocomplete="off" class="field__input" id="checkout_reduction_code" name="checkout[reduction_code]" placeholder="Gift card or discount code">
    Setting autocomplete="off" does not disable autofill.

autocomplete="off" should be valid according to https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete-off (despite browsers choosing to ignore it). Should this result in a warning?

Standardize `auditType` naming

During my refactoring of the audits, I introduced a field called auditType which has been used inconsistently. Sometimes it is used to represent when items DO NOT meet a criteria and are therefore invalid (e.g. autocomplete-valid), other times it is used to indicate which fields DO meet the criteria and are therefore invalid (e.g. autocomplete-off).

This issue is to standardize how auditType should be used. I'm leaning towards indicating which fields do meet the criteria and are therefore invalid. Examples:

  • autocomplete-invalid
  • autocomplete-off

Highlight problematic input field attributes for input-type-valid audit

The input-type-valid should highlight the problematic attribute to make it easier to scan.

Example: https://www.zara.com/us/en/signup

Unrecognized input types can lead to unexpected and incosistent user experiences

Found an input field with invalid types:

<input autocomplete="off" id="downshift-0-input" class="form-input-label__input form-input-autocomplete__input" placeholder=" " name="addressLines[0]" type="autocomplete" ...>

Should also fix the typo "incosistent".

The publish build step reports a success even though publish failed

https://github.com/GoogleChromeLabs/form-troubleshooter/runs/3282260568?check_suite_focus=true

{
  "kind": "chromewebstore#item",
  "id": "***",
  "uploadState": "FAILURE",
  "itemError": [
    {
      "error_code": "ITEM_NOT_UPDATABLE",
      "error_detail": "The item cannot be updated now because it is in pending review, ready to publish, or deleted status."
    }
  ]
}
{
  "error": {
    "code": 400,
    "message": "Publish condition not met: ",
    "errors": [
      {
        "message": "Publish condition not met: ",
        "domain": "chromewebstore.access",
        "reason": "badRequest"
      }
    ]
  }
}

showSaveFilePicker Must be handling a user gesture to show a file picker

The invocation of showSaveFilePicker needs a bit of a refactor because because the report markup is generated asynchronously. I suspect that with the following URL it is slower than others: https://www.ikea.com/gb/en/p/kalas-18-piece-cutlery-set-mixed-colours-70461385/

bundle.099f2.js:1 Uncaught (in promise) DOMException: Failed to execute 'showSaveFilePicker' on 'Window': Must be handling a user gesture to show a file picker.
    at chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:112026
    at Generator.next (<anonymous>)
    at a (chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:111583)
    at o (chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:111767)
    at chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:111845
    at new Promise (<anonymous>)
    at chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:111726
    at s (chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:112151)
    at u (chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:111884)
    at chrome-extension://plegimimpaegphlbibplaplcppgnjdnf/bundle.099f2.js:1:112483

Restore Save to HTML functionality

Describe the bug A clear and concise description of what the bug is.

Save to HTML functionality is/has been removed with the Preact integration (#22). This functionality should be restored.

image

Revise which fields should be audited when hidden

Hidden form fields should not fail some audits. Example: Help your users using alternate input methods complete this form by ensuring each field is correctly labeled

Hovering over the item results in the following error

Error in event handler: Error: Failed to execute 'querySelectorAll' on 'Document': 'html > body > div:nth-of-type(1) > div > div > main > div:nth-of-type(1) > form > div:nth-of-type(1) > div:nth-of-type(2) > div:nth-of-type(2) > div > div > input[-1]' is not a valid selector.

-1 should never be included in the css selector.

To Reproduce Steps to reproduce the behavior:

  1. Visit: https://partakefoods.com/
  2. Add an item to the cart
  3. Proceed to checkout
  4. Open the developer console
  5. Launch the extension
  6. Click on one of the issues (e.g. <input autocomplete="shipping given-name" class="visually-hidden" name="checkout[shipping_address][first_name]" type="text" ...>)
  7. See error

Expected behavior A clear and concise description of what you expected to happen.

Hidden fields should not be audited, and CSS selector should never return -1;

Screenshots If applicable, add screenshots to help explain your problem.

image

Error while viewing common mistakes with form-problems page

http://localhost:8080/?data=/test-data/form-problems.json#/mistakes

result-item.tsx:formatted:183 Uncaught (in promise) TypeError: Cannot read property 'map' of undefined
    at eval (result-item.tsx:formatted:183)
    at defaultItemRenderer (result-item.tsx:formatted:33)
    at eval (result-item.tsx:formatted:182)
    at eval (result-item.tsx:formatted:41)
    at Array.map (<anonymous>)
    at defaultItemsPresenter (result-item.tsx:formatted:38)
    at Object.render (result-item.tsx:formatted:181)
    at _.ResultItem [as constructor] (result-item.tsx:formatted:296)
    at _.O [as render] (preact.module.js:351)
    at j (preact.module.js:267)

Support for iframe input elements

What do you think about adding support for input elements that are iframe'd?

An example of this is Stripe Elements which places sensitive fields like payment information in an iframe to prevent the host page from accessing these details and reducing the developer's PCI exposure.

At the moment, this extension does not have visibility of these input fields and therefore is unable to audit them. Should these fields also be audited?

Example of one of the fields in action: https://q1loc.csb.app/card-element

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.