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

fix scanner debugging #611

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
16 changes: 7 additions & 9 deletions dist/autofill-debug.js

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

16 changes: 7 additions & 9 deletions dist/autofill.js

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

35 changes: 17 additions & 18 deletions docs/scanner-debugging.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
## Debugging the Scanner

**On most occasions it's probably easier to debug using the steps outlined at [this page](https://app.asana.com/0/1200930669568058/1204279134793324/f). You can revert to this script for more complex needs.**
We have snapshots of various forms within [test-forms](..%2Ftest-forms), these can be loaded
into `src/scanner-debug.html` for easier debugger.

You can load our `Scanner.debug.js` script into any HTML file to inspect what's happening with the matching algorithms, form analysis etc.
### Step 1: start the server

```bash
npm run server
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
npm run server
npm run serve

```

The file `src/scanner-debug.html` is there as an example, inside there's this script tag:
### Step 2: open the page

```html
<!-- snip -->
<script type="module" src="./Scanner.debug.js"></script>
<!-- snip -->
```
In any browser, load the following URL
- http://localhost:3210/src/scanner-debug.html

That will load the Scanner and initialize it on the current document. You then just need to run a local webserver
to view the code in the browser's debugging tools.
### Step 3: Start debugging

```bash
# run this to install `serve` globally. This is **not** required if you have other ways of running servers!
npm i -g serve
All JS files in this setup are loaded as native ESM modules, so all browser/IDE dev tools will
work as expected.

# now serve the `src` folder as the root - this is required for the ESM imports to work correctly
serve src
```
Note: The URL will be updated to reflect your selection, so you can share links with your colleagues.

### Step 4: Enable detailed logging

You should now be presented with a file-listing of everything in `src` -> just click on `scanner-debug.html` to start
debugging :)
When viewing any HTML form in this setup, you can append a `log` query parameter, this will
set `sessionStorage.setItem('ddg-autofill-debug', 'true')` and will output detailed information.
6 changes: 5 additions & 1 deletion src/DeviceInterface/InterfacePrototype.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {DeviceApi} from '../../packages/device-api/index.js'
import {
GetAutofillCredentialsCall,
StoreFormDataCall,
SendJSPixelCall
SendJSPixelCall,
AddDebugFlagCall
} from '../deviceApiCalls/__generated__/deviceApiCalls.js'
import {initFormSubmissionsApi} from './initFormSubmissionsApi.js'
import {EmailProtection} from '../EmailProtection.js'
Expand Down Expand Up @@ -313,6 +314,9 @@ class InterfacePrototype {

postInit () {
const cleanup = this.scanner.init()
if (this.globalConfig.isExtension) {
this.deviceApi.notify(new AddDebugFlagCall({ flag: 'autofill' }))
}
this.addLogoutListener(() => {
cleanup('Logged out')
if (this.globalConfig.isDDGDomain) {
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Form {
this.device = deviceInterface
this.hasShadowTree = hasShadowTree

/** @type Record<'all' | SupportedMainTypes, Set> */
/** @type {Record<'all' | SupportedMainTypes, Set>} */
this.inputs = {
all: new Set(),
credentials: new Set(),
Expand Down
87 changes: 80 additions & 7 deletions src/Scanner.debug.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { createScanner } from './Scanner.js'

sessionStorage.setItem('ddg-autofill-debug', 'true')

/**
* Scanner.debug.js
*
Expand All @@ -21,6 +19,12 @@ const mockInterface = {
inputType_credentials: true,
inputType_identities: true,
inputType_creditCards: true
},
populateDataIfNeeded: () => {
// console.log('populateDataIfNeeded');
},
Comment on lines +23 to +25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this still be here?

canAutofillType: () => {
return true
}
},
globalConfig: {
Expand All @@ -34,12 +38,81 @@ const mockInterface = {
},
attachTooltip (...args) {
console.log('device.attachTooltip', args)
},
isTooltipActive: () => {
return false
},
get scanner () {
return state.scanner
}
}

// @ts-ignore
const scanner = createScanner(mockInterface, {
initialDelay: 1 // allow debugging directly on macOS - if this was 0 then it would try to use requestIdleCallback, which is absent in WebKit
})
let state = {
/** @type {import('./Scanner.js').Scanner | undefined} */
scanner: undefined,
/** @type {HTMLSelectElement|null} */
list: document.querySelector('select[name="html-list"]')
}

const url = new URL(window.location.href)
const initial = url.searchParams.get('form')
const log = url.searchParams.has('log')

scanner.init()
if (log) {
sessionStorage.setItem('ddg-autofill-debug', 'true')
sessionStorage.setItem('ddg-autofill-perf', 'true')
} else {
sessionStorage.setItem('ddg-autofill-debug', 'false')
sessionStorage.setItem('ddg-autofill-perf', 'false')
}

loadList()
.then(() => {
if (initial) {
loadNewForm(initial).catch(console.error)
}
})

async function loadList () {
const url = new URL(`/test-forms/index.json`, window.location.href)
fetch(url)
.then(response => response.json())
.then(x => {
x.forEach(item => {
shakyShane marked this conversation as resolved.
Show resolved Hide resolved
const option = document.createElement('option')
option.value = item.html
option.textContent = item.html
state.list?.appendChild(option)
})
})
}
async function loadNewForm (filename) {
const url = new URL(`/test-forms/${filename}`, window.location.href)
fetch(url)
.then(response => response.text())
.then(html => {
let mainElement = document.querySelector('main')
if (mainElement) {
mainElement.innerHTML = html
if (state.list) {
state.list.value = filename
}
state.scanner = createScanner(/** @type {any} */(mockInterface), {
initialDelay: 1 // allow debugging directly on macOS - if this was 0 then it would try to use requestIdleCallback, which is absent in WebKit
})
state.scanner?.init()
} else {
console.log("'main' element not found on the page.")
}
})
.catch(error => {
console.error('Error:', error)
})
}

document.querySelector('select[name="html-list"]')?.addEventListener('change', (e) => {
const elem = /** @type {HTMLSelectElement} */(e.target)
const next = new URL(window.location.href)
next.searchParams.set('form', elem.value)
window.location.href = next.href
})
5 changes: 0 additions & 5 deletions src/Scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
shouldLog, pierceShadowTree,
findEnclosedElements
} from './autofill-utils.js'
import { AddDebugFlagCall } from './deviceApiCalls/__generated__/deviceApiCalls.js'

const {
MAX_INPUTS_PER_PAGE,
Expand Down Expand Up @@ -106,10 +105,6 @@ class DefaultScanner {
* @returns {(reason: string, ...rest) => void}
*/
init () {
if (this.device.globalConfig.isExtension) {
this.device.deviceApi.notify(new AddDebugFlagCall({ flag: 'autofill' }))
}

// Add the shadow DOM listener. Handlers in handleEvent
window.addEventListener('pointerdown', this, true)
// We don't listen for focus events on mobile, they can cause keyboard flashing
Expand Down
36 changes: 29 additions & 7 deletions src/scanner-debug.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,37 @@
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Scanner Test</title>
<style>
html, body {
margin: 0;
padding: 0;
}
.header {
padding: 1em;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
}
main {
padding: 1em;
}
</style>
</head>
<body>
<div>
<form action="">
<label for="email"><input type="text" id="email"></label>
<label for="password"><input type="password" id="password"></label>
<button type="submit">Sign in</button>
</form>
</div>
<script type="importmap">
{
"imports": {
"@duckduckgo/content-scope-scripts/src/apple-utils": "/node_modules/@duckduckgo/content-scope-scripts/src/apple-utils.js"
}
}
</script>
<header class="header">
<label>
Select a form:
<select name="html-list">
<option disabled selected></option>
</select>
</label>
</header>
<main><!-- Content will be loaded here --></main>
<script type="module" src="./Scanner.debug.js"></script>
</body>
</html>
16 changes: 7 additions & 9 deletions swift-package/Resources/assets/autofill-debug.js

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

Loading
Loading