Commit e4509d33 authored by Yiming Zhou's avatar Yiming Zhou Committed by Commit Bot

Adding fixes and features for the Action Recorder Extension.

1. Fixed an edge case where the Recorder UI is truncated by the parent
page's stylesheet. Added an explicit padding style to the Recorder UI.
2. Record page load events on the main frame. I can later use the page
load events to truncate test recipes.
3. Add a typePassword action.

Bug: 855284
Change-Id: Ieac830addbc7dff303ab456438328ffd64e12953
Reviewed-on: https://chromium-review.googlesource.com/1145624
Commit-Queue: Yiming Zhou <uwyiming@google.com>
Reviewed-by: default avatarJared Saul <jsaul@google.com>
Cr-Commit-Position: refs/heads/master@{#577771}
parent fcb791e8
...@@ -660,6 +660,20 @@ ...@@ -660,6 +660,20 @@
// occur on 'about:'' pages such as the blank page. Plus, this // occur on 'about:'' pages such as the blank page. Plus, this
// extension has no permission to access 'about:' pages. // extension has no permission to access 'about:' pages.
!details.url.startsWith('about:')) { !details.url.startsWith('about:')) {
// If the tab's root frame loaded a new page, log the page's url.
// An engineer can truncate a test recipe generated for captured sites
// using the 'loadPage' actions. If the Web Page Replay (WPR) tool can
// serve a 'loadPage' action url, then the engineer can delete all the
// actions that precedes the 'loadPage' action.
if (details.frameId === 0) {
addActionToRecipe({
url: details.url,
context: { 'isIframe': false },
type: 'loadPage'
});
}
startRecordingOnTabAndFrame(tabId, details.frameId) startRecordingOnTabAndFrame(tabId, details.frameId)
.then(() => getRecordingState()) .then(() => getRecordingState())
.then((state) => { .then((state) => {
......
...@@ -290,7 +290,28 @@ ...@@ -290,7 +290,28 @@
} }
} else if (lastTypingEventTargetValue === event.target.value) { } else if (lastTypingEventTargetValue === event.target.value) {
console.log(`Typing detected on: ${selector}`); console.log(`Typing detected on: ${selector}`);
action.type = 'type';
// Distinguish between typing inside password input fields and
// other type of text input fields.
//
// This extension generates test recipes to be consumed by the Captured
// Sites Automation Framework. The automation framework replays a typing
// action by using JavaScript to set the value of a text input field.
// However, to trigger the Chrome Password Manager, the automation
// framework must simulate user typing inside the password field by
// sending individual character keyboard input - because Chrome Password
// Manager deliberately ignores forms filled by JavaScript.
//
// Simulating keyboard input is a less reliable and therefore the less
// preferred way for filling text inputs. The Automation Framework uses
// keyboard input only when necessary. So this extension separates
// typing password actions from other typing actions.
if (isPasswordInputElement(event.target)) {
action.type = 'typePassword';
} else {
action.type = 'type';
}
action.value = event.target.value; action.value = event.target.value;
addActionToRecipe(action); addActionToRecipe(action);
} else { } else {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
panelUi.src = chrome.runtime.getURL('content/panel.html'); panelUi.src = chrome.runtime.getURL('content/panel.html');
panelUi.style.border = 'none'; panelUi.style.border = 'none';
panelUi.style.height = '613px'; panelUi.style.height = '613px';
panelUi.style.padding = '0';
panelUi.style.position = 'fixed'; panelUi.style.position = 'fixed';
panelUi.style.right = 0; panelUi.style.right = 0;
panelUi.style.top = '100px'; panelUi.style.top = '100px';
......
...@@ -65,6 +65,12 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -65,6 +65,12 @@ document.addEventListener('DOMContentLoaded', () => {
actionLabel.textContent = 'hover'; actionLabel.textContent = 'hover';
actionDetailLabel.textContent = `hover over element`; actionDetailLabel.textContent = `hover over element`;
break; break;
case 'loadPage':
actionLabel.textContent = 'loaded page';
actionDetailLabel.textContent = 'loaded a new page';
selectorLabel.textContent = action.url;
selectorDetailLabel.textContent = action.url;
break;
case 'pressEnter': case 'pressEnter':
actionLabel.textContent = 'enter'; actionLabel.textContent = 'enter';
actionDetailLabel.textContent = `press enter`; actionDetailLabel.textContent = `press enter`;
...@@ -77,6 +83,10 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -77,6 +83,10 @@ document.addEventListener('DOMContentLoaded', () => {
actionLabel.textContent = 'type'; actionLabel.textContent = 'type';
actionDetailLabel.textContent = `type '${action.value}'`; actionDetailLabel.textContent = `type '${action.value}'`;
break; break;
case 'typePassword':
actionLabel.textContent = 'type password';
actionDetailLabel.textContent = `type '${action.value}'`;
break;
case 'validateField': case 'validateField':
actionLabel.textContent = 'validate'; actionLabel.textContent = 'validate';
actionDetailLabel.textContent = `check that field actionDetailLabel.textContent = `check that field
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment