Npm run format
This commit is contained in:
Родитель
b32e38fa2a
Коммит
f174c3b17c
18
DEV.md
18
DEV.md
|
@ -34,6 +34,7 @@ After cloning the repo, you can run the following commands from the top level di
|
|||
$ npm install
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
This packages the add-on into an xpi file which is stored in `dist/`. This file is what you load into Firefox.
|
||||
|
||||
## General notes on Shield Study Engineering
|
||||
|
@ -52,8 +53,8 @@ You can have Firefox automatically launched and the add-on installed by running:
|
|||
|
||||
To load the extension manually instead, open (preferably) the [Developer Edition of Firefox](https://www.mozilla.org/firefox/developer/) and load the `.xpi` using the following steps:
|
||||
|
||||
* Navigate to *about:config* and set `extensions.legacy.enabled` to `true`. This permits the loading of the embedded Web Extension since new versions of Firefox are becoming restricted to pure Web Extensions only.
|
||||
* Navigate to *about:debugging* in your URL bar
|
||||
* Navigate to _about:config_ and set `extensions.legacy.enabled` to `true`. This permits the loading of the embedded Web Extension since new versions of Firefox are becoming restricted to pure Web Extensions only.
|
||||
* Navigate to _about:debugging_ in your URL bar
|
||||
* Select "Load Temporary Add-on"
|
||||
* Find and select the latest xpi file you just built.
|
||||
|
||||
|
@ -61,7 +62,7 @@ To load the extension manually instead, open (preferably) the [Developer Edition
|
|||
|
||||
To debug installation and loading of the add-on:
|
||||
|
||||
* Navigate to *about:config* and set `shield.testing.logging.level` to `10`. This permits shield-add-on log output in browser console
|
||||
* Navigate to _about:config_ and set `shield.testing.logging.level` to `10`. This permits shield-add-on log output in browser console
|
||||
* Open the Browser Console using Firefox's top menu at `Tools > Web Developer > Browser Console`. This will display Shield (loading/telemetry) and log output from the add-on.
|
||||
|
||||
See [TESTPLAN.md](./TESTPLAN.md) for more details on how to see this add-on in action and hot it is expected to behave.
|
||||
|
@ -74,11 +75,11 @@ Note: This runs in a recently created profile. To have the study run despite the
|
|||
|
||||
## Automated testing
|
||||
|
||||
`npm run test` verifies the telemetry payload as expected at Firefox startup and add-on installation in a clean profile, then does **optimistic testing** of the *commonest path* though the study for a user
|
||||
`npm run test` verifies the telemetry payload as expected at Firefox startup and add-on installation in a clean profile, then does **optimistic testing** of the _commonest path_ though the study for a user
|
||||
|
||||
- prove the notification bar ui opens
|
||||
- *clicking on the left-most button presented*.
|
||||
- verifying that sent Telemetry is correct.
|
||||
* prove the notification bar ui opens
|
||||
* _clicking on the left-most button presented_.
|
||||
* verifying that sent Telemetry is correct.
|
||||
|
||||
Code at [/test/functional_test.js](/test/functional_test.js).
|
||||
|
||||
|
@ -92,7 +93,7 @@ You can automatically build recent changes and package them into a `.xpi` by run
|
|||
|
||||
`$ npm run watch`
|
||||
|
||||
Now, anytime a file is changed and saved, node will repackage the add-on. You must reload the add-on as before, or by clicking the "Reload" under the add-on in *about:debugging*. Note that a hard re-load is recommended to clear local storage. To do this, simply remove the add-on and reload as before.
|
||||
Now, anytime a file is changed and saved, node will repackage the add-on. You must reload the add-on as before, or by clicking the "Reload" under the add-on in _about:debugging_. Note that a hard re-load is recommended to clear local storage. To do this, simply remove the add-on and reload as before.
|
||||
|
||||
Note: This is currently only useful if you load the extension manually - it has no effect when running `npm run firefox`.
|
||||
|
||||
|
@ -154,7 +155,6 @@ Note: This is currently only useful if you load the extension manually - it has
|
|||
└── tutorial.md
|
||||
|
||||
>> tree -a -I 'node_modules|.git|.DS_Store'
|
||||
|
||||
```
|
||||
|
||||
This structure is set forth in [shield-studies-addon-template](https://github.com/mozilla/shield-studies-addon-template), with study-specific changes found mostly in `addon/lib`, `addon/webextension` and `addon/Config.jsm`.
|
||||
|
|
|
@ -14,11 +14,11 @@ In an effort to move to WebExtensions, we are also working on making a Shield st
|
|||
|
||||
## About This Study
|
||||
|
||||
**Note**: This is toy / demonstration [Shield Study](https://wiki.mozilla.org/Firefox/Shield/Shield_Studies) Legacy Addon. Use this as a template for yours
|
||||
**Note**: This is toy / demonstration [Shield Study](https://wiki.mozilla.org/Firefox/Shield/Shield_Studies) Legacy Addon. Use this as a template for yours
|
||||
|
||||
(Note: get these from your PHD).
|
||||
|
||||
Goal: Determine which if any TOOLBAR BUTTONS DESIGNS is the most enticing to the user.
|
||||
Goal: Determine which if any TOOLBAR BUTTONS DESIGNS is the most enticing to the user.
|
||||
|
||||
## Seeing the add-on in action
|
||||
|
||||
|
@ -27,7 +27,8 @@ See [TESTPLAN.md](./TESTPLAN.md) for more details on how to get the add-on insta
|
|||
## Data Collected / Telemetry Pings
|
||||
|
||||
Measure:
|
||||
- Button (BrowserAction) usage.
|
||||
|
||||
* Button (BrowserAction) usage.
|
||||
|
||||
See [TELEMETRY.md](./TELEMETRY.md) for more details on what pings are sent by this add-on.
|
||||
|
||||
|
@ -35,7 +36,7 @@ See [TELEMETRY.md](./TELEMETRY.md) for more details on what pings are sent by th
|
|||
|
||||
Telemetry pings are loaded into S3 and re:dash. Sample query:
|
||||
|
||||
* [All pings](https://sql.telemetry.mozilla.org/queries/{#your-id}/source#table)
|
||||
* [All pings](https://sql.telemetry.mozilla.org/queries/{#your-id}/source#table)
|
||||
|
||||
## Improving this add-on
|
||||
|
||||
|
|
24
TELEMETRY.md
24
TELEMETRY.md
|
@ -2,18 +2,18 @@
|
|||
|
||||
## Usual Firefox Telemetry is unaffected.
|
||||
|
||||
- No change: `main` and other pings are UNAFFECTED by this add-on.
|
||||
- Respects telemetry preferences. If user has disabled telemetry, no telemetry will be sent.
|
||||
* No change: `main` and other pings are UNAFFECTED by this add-on.
|
||||
* Respects telemetry preferences. If user has disabled telemetry, no telemetry will be sent.
|
||||
|
||||
## Study-specific endings
|
||||
## Study-specific endings
|
||||
|
||||
This study has no surveys and as such has NO SPECIFIC ENDINGS.
|
||||
|
||||
The STUDY SPECIFIC ENDINGS this study supports are:
|
||||
|
||||
- "voted",
|
||||
- "notification-x"
|
||||
- "window-or-fx-closed"
|
||||
* "voted",
|
||||
* "notification-x"
|
||||
* "window-or-fx-closed"
|
||||
|
||||
## `shield-study` pings (common to all shield-studies)
|
||||
|
||||
|
@ -23,24 +23,24 @@ The STUDY SPECIFIC ENDINGS this study supports are:
|
|||
|
||||
Events instrumented in this study:
|
||||
|
||||
- UI
|
||||
- prompted (notification bar is shown)
|
||||
* UI
|
||||
|
||||
- Interactions
|
||||
- voted
|
||||
* prompted (notification bar is shown)
|
||||
|
||||
* Interactions
|
||||
* voted
|
||||
|
||||
All interactions with the UI create sequences of Telemetry Pings.
|
||||
|
||||
All UI `shield-study` `study_state` sequences look like this:
|
||||
|
||||
- `enter => install => (one of: "voted" | "notification-x" | "window-or-fx-closed") => exit`.
|
||||
* `enter => install => (one of: "voted" | "notification-x" | "window-or-fx-closed") => exit`.
|
||||
|
||||
## Example sequence for a 'voted => not sure' interaction
|
||||
|
||||
These are the `payload` fields from all pings in the `shield-study` and `shield-study-addon` buckets.
|
||||
|
||||
```
|
||||
|
||||
// common fields
|
||||
|
||||
branch up-to-expectations-1 // should describe Question text
|
||||
|
|
88
TESTPLAN.md
88
TESTPLAN.md
|
@ -9,7 +9,7 @@
|
|||
### Install the add-on and enroll in the study
|
||||
|
||||
* (Create profile: <https://developer.mozilla.org/Firefox/Multiple_profiles>, or via some other method)
|
||||
* Navigate to *about:config* and set the following preferences. (If a preference does not exist, create it be right-clicking in the white area and selecting New -> String or Integer depending on the type of preference)
|
||||
* Navigate to _about:config_ and set the following preferences. (If a preference does not exist, create it be right-clicking in the white area and selecting New -> String or Integer depending on the type of preference)
|
||||
* Set `extensions.legacy.enabled` to `true`. This permits the loading of the embedded Web Extension since new versions of Firefox are becoming restricted to pure Web Extensions only.
|
||||
* Set `shield.test.variation` to `kitten`.
|
||||
* Go to [this study's tracking bug](tbd: replace with your studys launch bug link in bugzilla) and install the latest signed XPI
|
||||
|
@ -18,17 +18,17 @@
|
|||
|
||||
Users see:
|
||||
|
||||
- an icon in the browser address bar (webExtension BrowserAction) with one of 3 images (Cat, Dog, Lizard)
|
||||
* an icon in the browser address bar (webExtension BrowserAction) with one of 3 images (Cat, Dog, Lizard)
|
||||
|
||||
Clicking on the button:
|
||||
|
||||
- changes the badge
|
||||
- sends telemetry
|
||||
* changes the badge
|
||||
* sends telemetry
|
||||
|
||||
ONCE ONLY users see:
|
||||
|
||||
- a notification bar, introducing the featur
|
||||
- allowing them to opt out
|
||||
* a notification bar, introducing the featur
|
||||
* allowing them to opt out
|
||||
|
||||
Icon will be the same every run.
|
||||
|
||||
|
@ -36,61 +36,61 @@ If the user clicks on the badge more than 3 times, it ends the study.
|
|||
|
||||
### Do these tests
|
||||
|
||||
1. UI APPEARANCE. OBSERVE a notification bar with these traits:
|
||||
1. UI APPEARANCE. OBSERVE a notification bar with these traits:
|
||||
|
||||
* Icon is 'heartbeat'
|
||||
* Text is one of 8 selected "questions", such as: "Do you like Firefox?". These are listed in [/addon/Config.jsm](/addon/Config.jsm) as the variable `weightedVariations`.
|
||||
* clickable buttons with labels 'yes | not sure | no' OR 'no | not sure | yes' (50/50 chance of each)
|
||||
* an `x` button at the right that closes the notice.
|
||||
* Icon is 'heartbeat'
|
||||
* Text is one of 8 selected "questions", such as: "Do you like Firefox?". These are listed in [/addon/Config.jsm](/addon/Config.jsm) as the variable `weightedVariations`.
|
||||
* clickable buttons with labels 'yes | not sure | no' OR 'no | not sure | yes' (50/50 chance of each)
|
||||
* an `x` button at the right that closes the notice.
|
||||
|
||||
Test fails IF:
|
||||
Test fails IF:
|
||||
|
||||
- there is no bar.
|
||||
- elements are not correct or are not displaye
|
||||
* there is no bar.
|
||||
* elements are not correct or are not displaye
|
||||
|
||||
2. UI functionality: VOTE
|
||||
2. UI functionality: VOTE
|
||||
|
||||
Expect: Click on a 'vote' button (any of: `yes | not sure | no`) has all these effects
|
||||
Expect: Click on a 'vote' button (any of: `yes | not sure | no`) has all these effects
|
||||
|
||||
- notice closes
|
||||
- addon uninstalls
|
||||
- no additional tabs open
|
||||
- telemetry pings are 'correct' with this SPECIFIC `study_state` as the ending
|
||||
* notice closes
|
||||
* addon uninstalls
|
||||
* no additional tabs open
|
||||
* telemetry pings are 'correct' with this SPECIFIC `study_state` as the ending
|
||||
|
||||
- ending is `voted`
|
||||
- 'vote' is correct.
|
||||
* ending is `voted`
|
||||
* 'vote' is correct.
|
||||
|
||||
3. UI functionality: 'X' button
|
||||
3. UI functionality: 'X' button
|
||||
|
||||
Click on the 'x' button.
|
||||
Click on the 'x' button.
|
||||
|
||||
- notice closes
|
||||
- addon uninstalls
|
||||
- no additional tabs open
|
||||
- telemetry pings are 'correct' with this SPECIFIC ending
|
||||
* notice closes
|
||||
* addon uninstalls
|
||||
* no additional tabs open
|
||||
* telemetry pings are 'correct' with this SPECIFIC ending
|
||||
|
||||
- ending is `notification-x`
|
||||
* ending is `notification-x`
|
||||
|
||||
4. UI functionality 'close window'
|
||||
4. UI functionality 'close window'
|
||||
|
||||
1. Open a 2nd Firefox window.
|
||||
2. Close the initial window.
|
||||
1. Open a 2nd Firefox window.
|
||||
2. Close the initial window.
|
||||
|
||||
Then observe:
|
||||
Then observe:
|
||||
|
||||
- notice closes
|
||||
- addon uninstalls
|
||||
- no additional tabs open
|
||||
- telemetry pings are 'correct' with this SPECIFIC ending
|
||||
* notice closes
|
||||
* addon uninstalls
|
||||
* no additional tabs open
|
||||
* telemetry pings are 'correct' with this SPECIFIC ending
|
||||
|
||||
- ending is `window-or-fx-closed`
|
||||
* ending is `window-or-fx-closed`
|
||||
|
||||
5. UI functionality 'too-popular'
|
||||
5. UI functionality 'too-popular'
|
||||
|
||||
* Click on the web extension's icon three times
|
||||
* Verify that the study ends
|
||||
* Verify that sent Telemetry is correct
|
||||
* Verify that the user is sent to the URL specified in `addon/Config.jsm` under `endings -> too-popular`.
|
||||
* Click on the web extension's icon three times
|
||||
* Verify that the study ends
|
||||
* Verify that sent Telemetry is correct
|
||||
* Verify that the user is sent to the URL specified in `addon/Config.jsm` under `endings -> too-popular`.
|
||||
|
||||
### Note: checking "sent Telemetry is correct"
|
||||
|
||||
|
@ -102,7 +102,7 @@ See [TELEMETRY.md](./TELEMETRY.md) for more details on what pings are sent by th
|
|||
|
||||
To debug installation and loading of the add-on:
|
||||
|
||||
* Navigate to *about:config* and set `shield.testing.logging.level` to `10`. This permits shield-add-on log output in browser console (If the preference does not exist, create it be right-clicking in the white area and selecting New -> Integer)
|
||||
* Navigate to _about:config_ and set `shield.testing.logging.level` to `10`. This permits shield-add-on log output in browser console (If the preference does not exist, create it be right-clicking in the white area and selecting New -> Integer)
|
||||
* Open the Browser Console using Firefox's top menu at `Tools > Web Developer > Browser Console`. This will display Shield (loading/telemetry) and log output from the add-on.
|
||||
|
||||
Example log output after installing the addon:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Windows Development and Testing
|
||||
# Windows Development and Testing
|
||||
|
||||
The Shield Studies Addon Template makes some assumptions about your environment that can be challenging to meet on Windows machines. So far the most promising approach uses the **Windows Subsystem for Linux (WSL)**. WSL is a young project with bugs and unexpected pitfalls; caveat emptor.
|
||||
The Shield Studies Addon Template makes some assumptions about your environment that can be challenging to meet on Windows machines. So far the most promising approach uses the **Windows Subsystem for Linux (WSL)**. WSL is a young project with bugs and unexpected pitfalls; caveat emptor.
|
||||
|
||||
## Requirements
|
||||
|
||||
|
@ -9,19 +9,23 @@ The Shield Studies Addon Template makes some assumptions about your environment
|
|||
## Installing WSL
|
||||
|
||||
1. [Follow Microsoft's official steps for installing WSL](https://answers.microsoft.com/en-us/insider/wiki/insider_wintp-insider_install/how-to-enable-the-windows-subsystem-for-linux/16e8f2e8-4a6a-4325-a89a-fd28c7841775?auth=1). These instructions are clear and detailed. _If you prefer, here is a TL;DR:_
|
||||
1. Enable developer mode in Windows 10 in `Start > Settings > Update & security > For developers`.
|
||||
2. Enable the optional Windows feature, "Windows Subsystem for Linux" using `optionalfeatures.exe`.
|
||||
3. Restart.
|
||||
4. Type `bash` at the Windows command line and wait for Ubuntu to install.
|
||||
|
||||
1. Enable developer mode in Windows 10 in `Start > Settings > Update & security > For developers`.
|
||||
2. Enable the optional Windows feature, "Windows Subsystem for Linux" using `optionalfeatures.exe`.
|
||||
3. Restart.
|
||||
4. Type `bash` at the Windows command line and wait for Ubuntu to install.
|
||||
|
||||
2. Install a recent version of node.js:
|
||||
|
||||
```
|
||||
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
3. Get the latest npm: `npm install npm@latest -g`
|
||||
|
||||
4. Install git and zip (and any other linux command-line tools you like):
|
||||
|
||||
```
|
||||
sudo apt install git
|
||||
sudo apt install zip
|
||||
|
@ -43,4 +47,4 @@ sudo apt install zip
|
|||
|
||||
* Windows-first developers, improve any/all of the above information.
|
||||
* Windows-first developers, help find workarounds to bugs encountered.
|
||||
* Windows-first developers, script any of the above steps to improve this setup process.
|
||||
* Windows-first developers, script any of the above steps to improve this setup process.
|
||||
|
|
|
@ -12,7 +12,7 @@ var EXPORTED_SYMBOLS = ["config"];
|
|||
|
||||
var config = {
|
||||
// required STUDY key
|
||||
"study": {
|
||||
study: {
|
||||
/** Required for studyUtils.setup():
|
||||
*
|
||||
* - studyName
|
||||
|
@ -28,7 +28,7 @@ var config = {
|
|||
// required keys: studyName, endings, telemetry
|
||||
|
||||
// will be used activeExperiments tagging
|
||||
"studyName": "buttonFeatureExperiment",
|
||||
studyName: "buttonFeatureExperiment",
|
||||
|
||||
/** **endings**
|
||||
* - keys indicate the 'endStudy' even that opens these.
|
||||
|
@ -37,47 +37,47 @@ var config = {
|
|||
* - If there is no key for an endStudy reason, no url will open.
|
||||
* - usually surveys, orientations, explanations
|
||||
*/
|
||||
"endings": {
|
||||
endings: {
|
||||
/** standard endings */
|
||||
"user-disable": {
|
||||
"baseUrl": "http://www.example.com/?reason=user-disable",
|
||||
baseUrl: "http://www.example.com/?reason=user-disable",
|
||||
},
|
||||
"ineligible": {
|
||||
"baseUrl": "http://www.example.com/?reason=ineligible",
|
||||
ineligible: {
|
||||
baseUrl: "http://www.example.com/?reason=ineligible",
|
||||
},
|
||||
"expired": {
|
||||
"baseUrl": "http://www.example.com/?reason=expired",
|
||||
expired: {
|
||||
baseUrl: "http://www.example.com/?reason=expired",
|
||||
},
|
||||
/** User defined endings */
|
||||
"used-often": {
|
||||
"baseUrl": "http://www.example.com/?reason=used-often",
|
||||
"study_state": "ended-positive", // neutral is default
|
||||
baseUrl: "http://www.example.com/?reason=used-often",
|
||||
study_state: "ended-positive", // neutral is default
|
||||
},
|
||||
"a-non-url-opening-ending": {
|
||||
"study_state": "ended-neutral",
|
||||
"baseUrl": null,
|
||||
study_state: "ended-neutral",
|
||||
baseUrl: null,
|
||||
},
|
||||
"introduction-leave-study": {
|
||||
"study_state": "ended-negative",
|
||||
"baseUrl": "http://www.example.com/?reason=introduction-leave-study",
|
||||
study_state: "ended-negative",
|
||||
baseUrl: "http://www.example.com/?reason=introduction-leave-study",
|
||||
},
|
||||
},
|
||||
"telemetry": {
|
||||
"send": true, // assumed false. Actually send pings?
|
||||
"removeTestingFlag": false, // Marks pings to be discarded, set true for to have the pings processed in the pipeline
|
||||
telemetry: {
|
||||
send: true, // assumed false. Actually send pings?
|
||||
removeTestingFlag: false, // Marks pings to be discarded, set true for to have the pings processed in the pipeline
|
||||
// TODO "onInvalid": "throw" // invalid packet for schema? throw||log
|
||||
},
|
||||
},
|
||||
|
||||
// required LOG key
|
||||
"log": {
|
||||
log: {
|
||||
// Fatal: 70, Error: 60, Warn: 50, Info: 40, Config: 30, Debug: 20, Trace: 10, All: -1,
|
||||
"bootstrap": {
|
||||
bootstrap: {
|
||||
// Console.jsm uses "debug", whereas Log.jsm uses "Debug", *sigh*
|
||||
"level": "debug",
|
||||
level: "debug",
|
||||
},
|
||||
"studyUtils": {
|
||||
"level": "Trace",
|
||||
studyUtils: {
|
||||
level: "Trace",
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -85,7 +85,7 @@ var config = {
|
|||
|
||||
// a place to put an 'isEligible' function
|
||||
// Will run only during first install attempt
|
||||
"isEligible": async function() {
|
||||
async isEligible() {
|
||||
// get whatever prefs, addons, telemetry, anything!
|
||||
// Cu.import can see 'firefox things', but not package things.
|
||||
return true;
|
||||
|
@ -96,21 +96,21 @@ var config = {
|
|||
- downweight lizards. Lizards is a 'poison' branch, meant to
|
||||
help control for novelty effect
|
||||
*/
|
||||
"weightedVariations": [
|
||||
weightedVariations: [
|
||||
{
|
||||
"name": "kittens",
|
||||
"weight": 1.5,
|
||||
name: "kittens",
|
||||
weight: 1.5,
|
||||
},
|
||||
{
|
||||
"name": "puppers",
|
||||
"weight": 1.5,
|
||||
name: "puppers",
|
||||
weight: 1.5,
|
||||
},
|
||||
{
|
||||
"name": "lizard",
|
||||
"weight": 1,
|
||||
}, // we want more puppers in our sample
|
||||
name: "lizard",
|
||||
weight: 1,
|
||||
}, // we want more puppers in our sample
|
||||
],
|
||||
|
||||
// Optional: relative to bootstrap.js in the xpi
|
||||
"studyUtilsPath": `./StudyUtils.jsm`,
|
||||
studyUtilsPath: `./StudyUtils.jsm`,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
|
||||
/** Example Feature module for a Shield Study.
|
||||
*
|
||||
* UI:
|
||||
|
@ -27,8 +26,11 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
|
||||
const EXPORTED_SYMBOLS = ["Feature"];
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(
|
||||
this,
|
||||
"RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm",
|
||||
);
|
||||
|
||||
/** Return most recent NON-PRIVATE browser window, so that we can
|
||||
* manipulate chrome elements on it.
|
||||
|
@ -49,7 +51,6 @@ class Feature {
|
|||
*
|
||||
*/
|
||||
constructor(variation, studyUtils, reasonName, log) {
|
||||
|
||||
this.variation = variation; // unused. Some other UI might use the specific variation info for things.
|
||||
this.studyUtils = studyUtils;
|
||||
this.reasonName = reasonName;
|
||||
|
@ -57,17 +58,18 @@ class Feature {
|
|||
|
||||
// Example log statement
|
||||
this.log.debug("Feature constructor");
|
||||
|
||||
}
|
||||
|
||||
start() {
|
||||
this.log.debug("Feature start");
|
||||
|
||||
// perform something only during INSTALL and UPGRADE = a new study period begins
|
||||
if (this.reasonName === "ADDON_INSTALL" || this.reasonName === "ADDON_UPGRADE") {
|
||||
if (
|
||||
this.reasonName === "ADDON_INSTALL" ||
|
||||
this.reasonName === "ADDON_UPGRADE"
|
||||
) {
|
||||
this.introductionNotificationBar();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Display instrumented 'notification bar' explaining the feature to the user
|
||||
|
@ -92,7 +94,7 @@ class Feature {
|
|||
const recentWindow = getMostRecentBrowserWindow();
|
||||
const doc = recentWindow.document;
|
||||
const notificationBox = doc.querySelector(
|
||||
"#high-priority-global-notificationbox"
|
||||
"#high-priority-global-notificationbox",
|
||||
);
|
||||
|
||||
if (!notificationBox) return;
|
||||
|
@ -129,7 +131,7 @@ class Feature {
|
|||
},
|
||||
],
|
||||
// callback for nb events
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
// used by testing to confirm the bar is set with the correct config
|
||||
|
@ -137,7 +139,6 @@ class Feature {
|
|||
feature.telemetry({
|
||||
event: "introduction-shown",
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* good practice to have the literal 'sending' be wrapped up */
|
||||
|
@ -148,11 +149,9 @@ class Feature {
|
|||
/**
|
||||
* Called at end of study, and if the user disables the study or it gets uninstalled by other means.
|
||||
*/
|
||||
shutdown() {
|
||||
}
|
||||
shutdown() {}
|
||||
}
|
||||
|
||||
|
||||
// webpack:`libraryTarget: 'this'`
|
||||
this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
|
||||
this.Feature = Feature;
|
||||
|
|
34
package.json
34
package.json
|
@ -13,7 +13,8 @@
|
|||
"hasEmbeddedWebExtension": true,
|
||||
"chromeResource": "button-icon-preference",
|
||||
"creator": "Gregg Lind <glind@mozilla.com>",
|
||||
"description": "template shield study to serve a as base. This one is about Toolbar Buttons",
|
||||
"description":
|
||||
"template shield study to serve a as base. This one is about Toolbar Buttons",
|
||||
"bugzilla": "<tbd: bug to attach for signing>",
|
||||
"iconPath": "icon.png"
|
||||
},
|
||||
|
@ -51,12 +52,7 @@
|
|||
"node": ">=8.9.0"
|
||||
},
|
||||
"homepage": "http://github.com/mozilla/shield-studies-addon-template",
|
||||
"keywords": [
|
||||
"firefox",
|
||||
"legacy-addon",
|
||||
"mozilla",
|
||||
"shield-study"
|
||||
],
|
||||
"keywords": ["firefox", "legacy-addon", "mozilla", "shield-study"],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
@ -67,18 +63,26 @@
|
|||
"build": "bash ./bin/xpi.sh",
|
||||
"eslint": "eslint . --ext jsm --ext js --ext json",
|
||||
"eslint-fix": "eslint . --ext jsm --ext js --ext json --fix",
|
||||
"firefox": "export XPI=dist/linked-addon.xpi && npm run build && node run-firefox.js",
|
||||
"format": "prettier '**/*.{css,js,json,jsm,md}' --trailing-comma=all --ignore-path=.eslintignore --write && npm run eslint-fix",
|
||||
"harness_test": "export XPI=dist/linked-addon.xpi && mocha test/functional_tests.js --retry 2 --reporter json",
|
||||
"firefox":
|
||||
"export XPI=dist/linked-addon.xpi && npm run build && node run-firefox.js",
|
||||
"format":
|
||||
"prettier '**/*.{css,js,json,jsm,md}' --trailing-comma=all --ignore-path=.eslintignore --write && npm run eslint-fix",
|
||||
"harness_test":
|
||||
"export XPI=dist/linked-addon.xpi && mocha test/functional_tests.js --retry 2 --reporter json",
|
||||
"lint": "npm-run-all lint:*",
|
||||
"lint-build:addons-linter": "# actually a post build test: bin/addonLintTest ' + require('./package.json').name",
|
||||
"lint-build:addons-linter":
|
||||
"# actually a post build test: bin/addonLintTest ' + require('./package.json').name",
|
||||
"lint:addons-linter": "addons-linter addon/webextension/",
|
||||
"lint:eslint": "npm run eslint",
|
||||
"lint:fixpack": "fixpack",
|
||||
"lint:nsp": "nsp check",
|
||||
"prebuild": "cp node_modules/shield-studies-addon-utils/dist/StudyUtils.jsm addon/",
|
||||
"sign": "echo 'TBD, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1407757'",
|
||||
"test": "export XPI=dist/linked-addon.xpi && npm run build && mocha test/functional_tests.js --retry 2",
|
||||
"watch": "onchange 'addon/**' 'package.json' 'template/**' -e addon/install.rdf -e addon/chrome.manifest -e addon/StudyUtils.jsm -- npm run build -- '{{event}} {{changed}} $(date)'"
|
||||
"prebuild":
|
||||
"cp node_modules/shield-studies-addon-utils/dist/StudyUtils.jsm addon/",
|
||||
"sign":
|
||||
"echo 'TBD, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1407757'",
|
||||
"test":
|
||||
"export XPI=dist/linked-addon.xpi && npm run build && mocha test/functional_tests.js --retry 2",
|
||||
"watch":
|
||||
"onchange 'addon/**' 'package.json' 'template/**' -e addon/install.rdf -e addon/chrome.manifest -e addon/StudyUtils.jsm -- npm run build -- '{{event}} {{changed}} $(date)'"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +1,49 @@
|
|||
# Shield Study Template
|
||||
|
||||
`Shield-Study-Template` contains files for for making a **Shield Study Addon**. Shield Study Addons are **LEGACY ADDONS** for Firefox that include the **SHIELD-STUDIES-ADDON-UTILS** (`studyUtils.jsm`) file (4.1.x series).
|
||||
`Shield-Study-Template` contains files for for making a **Shield Study Addon**. Shield Study Addons are **LEGACY ADDONS** for Firefox that include the **SHIELD-STUDIES-ADDON-UTILS** (`studyUtils.jsm`) file (4.1.x series).
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
**Contents**
|
||||
|
||||
- [`npm` commands for `Shield-Study-Template`](#npm-commands-for-shield-study-template)
|
||||
- [What is a Shield Study?](#what-is-a-shield-study)
|
||||
- [tl;dr - Running the Template Study](#tldr---running-the-template-study)
|
||||
- [Folder Contents](#folder-contents)
|
||||
- [Parts of A Shield Study (General)](#parts-of-a-shield-study-general)
|
||||
- [Shield-Studies-Addon-Utils (`studyUtils.jsm`)](#shield-studies-addon-utils-studyutilsjsm)
|
||||
- [Legacy Addons](#legacy-addons)
|
||||
- [Building Your Feature, with Variations](#building-your-feature-with-variations)
|
||||
- [<span id="shield-telemetry">All About Shield Telemetry</span>](#span-idshield-telemetryall-about-shield-telemetryspan)
|
||||
- [Shield Study Telemetry Probe Life cycle](#shield-study-telemetry-probe-life-cycle)
|
||||
- [Expected ping counts](#expected-ping-counts)
|
||||
- [How Probes are Sent from `studyUtils.jsm`](#how-probes-are-sent-from-studyutilsjsm)
|
||||
- [Send your own probes](#send-your-own-probes)
|
||||
- [Viewing Sent Telemetry Probes](#viewing-sent-telemetry-probes)
|
||||
- [client](#client)
|
||||
- [Collector (example s.t.m.o query)](#collector-example-stmo-query)
|
||||
- [Engineering Side-by-Side (a/b) Feature Variations](#engineering-side-by-side-ab-feature-variations)
|
||||
- [Kittens or Puppers, the Critical Study We have all been waiting for](#kittens-or-puppers-the-critical-study-we-have-all-been-waiting-for)
|
||||
- [Get More Help](#get-more-help)
|
||||
- [Gotchas / FAQ / Ranting](#gotchas--faq--ranting)
|
||||
- [General](#general)
|
||||
- [studyUtils](#studyutils)
|
||||
- [Legacy Addons](#legacy-addons-1)
|
||||
- [s.t.m.o - sql.telemetry.mozilla.org](#stmo---sqltelemetrymozillaorg)
|
||||
- [Glossary](#glossary)
|
||||
- [OTHER DOCS](#other-docs)
|
||||
- [Configuration](#configuration)
|
||||
- [Lifecycle](#lifecycle)
|
||||
- [Running](#running)
|
||||
- [TODO](#todo)
|
||||
- [Links and References](#links-and-references)
|
||||
* [`npm` commands for `Shield-Study-Template`](#npm-commands-for-shield-study-template)
|
||||
* [What is a Shield Study?](#what-is-a-shield-study)
|
||||
* [tl;dr - Running the Template Study](#tldr---running-the-template-study)
|
||||
* [Folder Contents](#folder-contents)
|
||||
* [Parts of A Shield Study (General)](#parts-of-a-shield-study-general)
|
||||
* [Shield-Studies-Addon-Utils (`studyUtils.jsm`)](#shield-studies-addon-utils-studyutilsjsm)
|
||||
* [Legacy Addons](#legacy-addons)
|
||||
* [Building Your Feature, with Variations](#building-your-feature-with-variations)
|
||||
* [<span id="shield-telemetry">All About Shield Telemetry</span>](#span-idshield-telemetryall-about-shield-telemetryspan)
|
||||
* [Shield Study Telemetry Probe Life cycle](#shield-study-telemetry-probe-life-cycle)
|
||||
* [Expected ping counts](#expected-ping-counts)
|
||||
* [How Probes are Sent from `studyUtils.jsm`](#how-probes-are-sent-from-studyutilsjsm)
|
||||
* [Send your own probes](#send-your-own-probes)
|
||||
* [Viewing Sent Telemetry Probes](#viewing-sent-telemetry-probes)
|
||||
* [client](#client)
|
||||
* [Collector (example s.t.m.o query)](#collector-example-stmo-query)
|
||||
* [Engineering Side-by-Side (a/b) Feature Variations](#engineering-side-by-side-ab-feature-variations)
|
||||
* [Kittens or Puppers, the Critical Study We have all been waiting for](#kittens-or-puppers-the-critical-study-we-have-all-been-waiting-for)
|
||||
* [Get More Help](#get-more-help)
|
||||
* [Gotchas / FAQ / Ranting](#gotchas--faq--ranting)
|
||||
* [General](#general)
|
||||
* [studyUtils](#studyutils)
|
||||
* [Legacy Addons](#legacy-addons-1)
|
||||
* [s.t.m.o - sql.telemetry.mozilla.org](#stmo---sqltelemetrymozillaorg)
|
||||
* [Glossary](#glossary)
|
||||
* [OTHER DOCS](#other-docs)
|
||||
* [Configuration](#configuration)
|
||||
* [Lifecycle](#lifecycle)
|
||||
* [Running](#running)
|
||||
* [TODO](#todo)
|
||||
* [Links and References](#links-and-references)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## `npm` commands for `Shield-Study-Template`
|
||||
|
||||
|
||||
```
|
||||
"eslint": "eslint addon --ext jsm --ext js --ext json",
|
||||
"prebuild": "cp node_modules/shield-studies-addon-utils/dist/StudyUtils.jsm addon/",
|
||||
|
@ -58,53 +59,51 @@
|
|||
|
||||
**Shield Study Addons** do these actions:
|
||||
|
||||
- implement variations (1+) of a feature
|
||||
- report common study and addon lifecycle events to Telemetry
|
||||
- report study-specific data about how users react to and interact with a specific variations
|
||||
- respond coherently to addon life-cycle events (`install`, `startup`, `disable`, `uninstall`).
|
||||
|
||||
* implement variations (1+) of a feature
|
||||
* report common study and addon lifecycle events to Telemetry
|
||||
* report study-specific data about how users react to and interact with a specific variations
|
||||
* respond coherently to addon life-cycle events (`install`, `startup`, `disable`, `uninstall`).
|
||||
|
||||
## tl;dr - Running the Template Study
|
||||
|
||||
1. **One time**:
|
||||
1. **One time**:
|
||||
|
||||
* Clone this directory
|
||||
|
||||
```
|
||||
git clone template
|
||||
rm -rf {.git,docs}/
|
||||
git init
|
||||
```
|
||||
|
||||
* install dependencies, including [`mozilla/shield-studies-addon-utils`][mozilla-ssau].
|
||||
* Clone this directory
|
||||
|
||||
```
|
||||
npm install
|
||||
git clone template
|
||||
rm -rf {.git,docs}/
|
||||
git init
|
||||
```
|
||||
|
||||
* install dependencies, including [`mozilla/shield-studies-addon-utils`][mozilla-ssau].
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
* install **Firefox Nightly** for easier development
|
||||
|
||||
2. Edit and examine files:
|
||||
|
||||
- `addon/bootstrap.js`
|
||||
- `addon/Config.jsm`
|
||||
- `package.json`
|
||||
- `addon/lib/*`
|
||||
* `addon/bootstrap.js`
|
||||
* `addon/Config.jsm`
|
||||
* `package.json`
|
||||
* `addon/lib/*`
|
||||
|
||||
3. Build the legacy addon xpi. Run **Nightly** with addon
|
||||
3. Build the legacy addon xpi. Run **Nightly** with addon
|
||||
|
||||
`npm run firefox`
|
||||
`npm run firefox`
|
||||
|
||||
4. Debug using
|
||||
4. Debug using
|
||||
|
||||
- [`browser console`][link-browser-console]
|
||||
- `about:debugging`.
|
||||
* [`browser console`][link-browser-console]
|
||||
* `about:debugging`.
|
||||
|
||||
5. Restart / re-run after addon changes.
|
||||
5. Restart / re-run after addon changes.
|
||||
|
||||
Repeat Steps 2-5 as necessary.
|
||||
|
||||
|
||||
## Direcotry Contents
|
||||
|
||||
```
|
||||
|
@ -162,20 +161,18 @@ Repeat Steps 2-5 as necessary.
|
|||
├── test_harness.js
|
||||
├── test_printer.py
|
||||
└── utils.js
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Parts of A Shield Study (General)
|
||||
|
||||
Note: see [about the #kittens study](#kittens) for architecture of the particulars of the example study.
|
||||
|
||||
- Shield-Studies-Addon-Utils
|
||||
- Legacy Addon framing code
|
||||
- UI / Feature
|
||||
* Shield-Studies-Addon-Utils
|
||||
* Legacy Addon framing code
|
||||
* UI / Feature
|
||||
|
||||
- (optional) Web Extension, embedded
|
||||
- (optional) Various Firefox modules (`.jsm` files)
|
||||
* (optional) Web Extension, embedded
|
||||
* (optional) Various Firefox modules (`.jsm` files)
|
||||
|
||||
More details on each follow.
|
||||
|
||||
|
@ -184,50 +181,55 @@ More details on each follow.
|
|||
`studyUtils.jsm` is a Firefox JavaScript module that provides these capabilities:
|
||||
|
||||
1. **suggest variation for a client**
|
||||
- deterministic and predicatable: every startup will suggest the same variation for a particular client
|
||||
- per client: uses sha256 hash of (Telemetry Id, study name)
|
||||
|
||||
```javascript
|
||||
const variation = await studyUtils.deterministicVariation(myWeightedVariations);
|
||||
studyUtils.setVariation(variation);
|
||||
```
|
||||
* deterministic and predicatable: every startup will suggest the same variation for a particular client
|
||||
* per client: uses sha256 hash of (Telemetry Id, study name)
|
||||
|
||||
```javascript
|
||||
const variation = await studyUtils.deterministicVariation(myWeightedVariations);
|
||||
studyUtils.setVariation(variation);
|
||||
```
|
||||
|
||||
2. **Report lifecycle data** using Telemetry
|
||||
- `shield-study` Telemetry bucket
|
||||
- [about Shield Telemetry](#shield-telemetry)
|
||||
|
||||
```javascript
|
||||
// some study state events
|
||||
studyUtils.firstSeen();
|
||||
studyUtils.endStudy(reason);
|
||||
studyUtils.startup(ADDON_INSTALL);
|
||||
```
|
||||
* `shield-study` Telemetry bucket
|
||||
* [about Shield Telemetry](#shield-telemetry)
|
||||
|
||||
```javascript
|
||||
// some study state events
|
||||
studyUtils.firstSeen();
|
||||
studyUtils.endStudy(reason);
|
||||
studyUtils.startup(ADDON_INSTALL);
|
||||
```
|
||||
|
||||
3. **Report feature interaction and success data** using Telemetry
|
||||
- `shield-study-addon` Telemetry bucket
|
||||
|
||||
```javascript
|
||||
// values must be strings
|
||||
studyUtils.telemetry({evt:"click", button:"share", times:"3"})
|
||||
```
|
||||
* `shield-study-addon` Telemetry bucket
|
||||
|
||||
```javascript
|
||||
// values must be strings
|
||||
studyUtils.telemetry({ evt: "click", button: "share", times: "3" });
|
||||
```
|
||||
|
||||
4. **Annotate Telemetry Enviroment** to mark the user as special, and copy every `main` and other ping to a special bucket for faster analysis.
|
||||
|
||||
**Links** for `studyUtils` code:
|
||||
|
||||
- `npm install shield-studies-addon-utils`
|
||||
- `node_modules/shield-studies-addon-utils/dist/studyUtils.jsm`
|
||||
- Github: [mozilla/shield-studies-addon-utils](https://github.com/mozilla/shield-studies-addon-utils)
|
||||
|
||||
* `npm install shield-studies-addon-utils`
|
||||
* `node_modules/shield-studies-addon-utils/dist/studyUtils.jsm`
|
||||
* Github: [mozilla/shield-studies-addon-utils](https://github.com/mozilla/shield-studies-addon-utils)
|
||||
|
||||
### Legacy Addons
|
||||
|
||||
**Note**: to send Telemetry and see the ClientId, study addons require `Components.utils` (Chrome) privileges. Firefox webExtensions do not have those privileges. All Study Addons must be [Legacy Extensions][link-legacy].
|
||||
**Note**: to send Telemetry and see the ClientId, study addons require `Components.utils` (Chrome) privileges. Firefox webExtensions do not have those privileges. All Study Addons must be [Legacy Extensions][link-legacy].
|
||||
|
||||
A **Legacy Addon** consists of:
|
||||
|
||||
* files
|
||||
|
||||
- `bootstrap.js`
|
||||
- `install.rdf`
|
||||
- optional `chrome.manifest`, `update.rdf` etc.
|
||||
* `bootstrap.js`
|
||||
* `install.rdf`
|
||||
* optional `chrome.manifest`, `update.rdf` etc.
|
||||
|
||||
* build process to turn these files an `xpi`.
|
||||
* signing process using the [Legacy Signing Key][legacy-signing], to enable running in Beta and Release.
|
||||
|
@ -236,14 +238,12 @@ A **Legacy Addon** consists of:
|
|||
|
||||
If you have UI:
|
||||
|
||||
- embedded web extension - suggested (where possible). See [link-extensions]
|
||||
- jsm files
|
||||
* embedded web extension - suggested (where possible). See [link-extensions]
|
||||
* jsm files
|
||||
|
||||
If you do not have UI
|
||||
|
||||
- jsm files
|
||||
|
||||
|
||||
* jsm files
|
||||
|
||||
## <span id="shield-telemetry">Shield Telemetry Details</span>
|
||||
|
||||
|
@ -268,10 +268,8 @@ If you do not have UI
|
|||
|
|
||||
| (only if not installed)
|
||||
+-------------------> inelegible exit
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Expected ping counts
|
||||
|
||||
All **N** enters will eventually have an ending and an exit.
|
||||
|
@ -282,7 +280,6 @@ There will be **x** ineligibles ( \\( x \le N \\) ).
|
|||
|
||||
\\( N = i + x \\)
|
||||
|
||||
|
||||
```
|
||||
enter == exit
|
||||
== (install + ineligible)
|
||||
|
@ -296,50 +293,48 @@ Note:
|
|||
|
||||
`const su = Cu.import("resource://path/to/StudyUtils.jsm")`
|
||||
|
||||
`study_state` | `studyUtils` call | when to call it
|
||||
--- | --- | ---
|
||||
`enter` | `su.firstSeen()` | call ONCE per study during `ADDON_INSTALL`
|
||||
`install` | `su.startup(ADDON_INSTALL)` | During `boostrap.js:startup`
|
||||
none sent | `su.startup(<other reasons>)` | Never
|
||||
**ENDINGS** | | Affected by the `endings` config value.
|
||||
`user-disable` | `su.endStudy("user-disable")` | Implies user uninstalled or disabled addon, or (BUG) Normandy uninstalled it.
|
||||
`expired` | `su.endStudy("expired")` | Time-limited study reached expiration.
|
||||
`ended-positive` | `su.endStudy("ended-positive")` | General study-defined 'good ending', such as attempting to use feature.
|
||||
`ended-negative` | `su.endStudy("ended-negative")` | General study-defined 'bad ending', such as clicking 'I do not like this feature'.
|
||||
`ended-neutral` | `su.endStudy("ended-neutral")` | General study-defined 'neutral ending'.
|
||||
`ineligible` | `su.endStudy("ineligible")` | During install, client actually not appropriate for study, for some study-specific reason.
|
||||
**EXIT** | |
|
||||
`exit` | | automatically sent as part of `endStudy`
|
||||
| `study_state` | `studyUtils` call | when to call it |
|
||||
| ---------------- | ------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `enter` | `su.firstSeen()` | call ONCE per study during `ADDON_INSTALL` |
|
||||
| `install` | `su.startup(ADDON_INSTALL)` | During `boostrap.js:startup` |
|
||||
| none sent | `su.startup(<other reasons>)` | Never |
|
||||
| **ENDINGS** | | Affected by the `endings` config value. |
|
||||
| `user-disable` | `su.endStudy("user-disable")` | Implies user uninstalled or disabled addon, or (BUG) Normandy uninstalled it. |
|
||||
| `expired` | `su.endStudy("expired")` | Time-limited study reached expiration. |
|
||||
| `ended-positive` | `su.endStudy("ended-positive")` | General study-defined 'good ending', such as attempting to use feature. |
|
||||
| `ended-negative` | `su.endStudy("ended-negative")` | General study-defined 'bad ending', such as clicking 'I do not like this feature'. |
|
||||
| `ended-neutral` | `su.endStudy("ended-neutral")` | General study-defined 'neutral ending'. |
|
||||
| `ineligible` | `su.endStudy("ineligible")` | During install, client actually not appropriate for study, for some study-specific reason. |
|
||||
| **EXIT** | |
|
||||
| `exit` | | automatically sent as part of `endStudy` |
|
||||
|
||||
**Note**: Every user should have
|
||||
|
||||
**Note**: Every user should have
|
||||
|
||||
- exactly 1 each of ENTER, EXIT
|
||||
- exactly 1 of either INSTALL or INELGIBLE
|
||||
- exactly one 'ending' ping (which might be INELIGIBLE, EXPIRED, USER-DISABLE, ENDED-*)
|
||||
* exactly 1 each of ENTER, EXIT
|
||||
* exactly 1 of either INSTALL or INELGIBLE
|
||||
* exactly one 'ending' ping (which might be INELIGIBLE, EXPIRED, USER-DISABLE, ENDED-\*)
|
||||
|
||||
**Note**: [Full Schemas - gregglind/shield-study-schemas](https://github.com/gregglind/shield-study-schemas/tree/master/schemas-client)
|
||||
|
||||
|
||||
### Send your own probes
|
||||
|
||||
Use: `shieldStudy.telemetry(anObjectWithStringValues)`
|
||||
|
||||
This will send data to the `shield-study-addon` bucket. The `key=>string` map will be the `payload.data.attributes` key.
|
||||
This will send data to the `shield-study-addon` bucket. The `key=>string` map will be the `payload.data.attributes` key.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
// values must be strings
|
||||
studyUtils.telemetry({evt:"click", button:"share", times:"3"})
|
||||
studyUtils.telemetry({ evt: "click", button: "share", times: "3" });
|
||||
```
|
||||
|
||||
### Defining Custom Study Endings
|
||||
|
||||
Suppose you want some 'early endings', such as:
|
||||
|
||||
- positive: user reached "end of the built UI".
|
||||
- negative: user clicked on "no thanks".
|
||||
* positive: user reached "end of the built UI".
|
||||
* negative: user clicked on "no thanks".
|
||||
|
||||
Define in `endings`:
|
||||
|
||||
|
@ -359,28 +354,27 @@ Then:
|
|||
studyUtils.endStudy("user-attempted-signup");
|
||||
```
|
||||
|
||||
|
||||
## Viewing Sent Telemetry Probes
|
||||
|
||||
### client
|
||||
|
||||
1. **Use the QA Helper Addon**
|
||||
1. **Use the QA Helper Addon**
|
||||
|
||||
The QA-Shield-Study-Helper lists the `payload.data` field for every `shield-study` and `shield-study-addon` ping.
|
||||
The QA-Shield-Study-Helper lists the `payload.data` field for every `shield-study` and `shield-study-addon` ping.
|
||||
|
||||
[Bugzilla for QA Helper Addon](https://bugzilla.mozilla.org/show_bug.cgi?id=1407757
|
||||
)
|
||||
[direct install link for Signed XPI for @qa-shield-study-helper-1.0.0.xpi][qa-helper-addon-direct]
|
||||
[Bugzilla for QA Helper Addon](https://bugzilla.mozilla.org/show_bug.cgi?id=1407757)
|
||||
[direct install link for Signed XPI for @qa-shield-study-helper-1.0.0.xpi][qa-helper-addon-direct]
|
||||
|
||||
Example output:
|
||||
Example output:
|
||||
|
||||
```text
|
||||
// common fields
|
||||
```text
|
||||
// common fields
|
||||
|
||||
branch up-to-expectations-1 // should describe Question text
|
||||
study_name 57-perception-shield-study
|
||||
addon_version 1.0.0
|
||||
version 3
|
||||
branch up-to-expectations-1 // should describe Question text
|
||||
study_name 57-perception-shield-study
|
||||
addon_version 1.0.0
|
||||
version 3
|
||||
```
|
||||
|
||||
|
||||
2017-10-09T14:16:18.042Z shield-study
|
||||
|
@ -421,208 +415,180 @@ studyUtils.endStudy("user-attempted-signup");
|
|||
}
|
||||
```
|
||||
|
||||
2. Use `about:telemetry`, and look for `shield-study` or `shield-study-addon` probes.
|
||||
|
||||
|
||||
2. Use `about:telemetry`, and look for `shield-study` or `shield-study-addon` probes.
|
||||
|
||||
### Collector (example s.t.m.o query)
|
||||
|
||||
[Example s.t.m.o study states query for "Pioneer Enrollement"][stmo-study-states] shows the Study lifecycle for every client in the Pioneer Enrollment study.
|
||||
|
||||
|
||||
|
||||
## Engineering Side-by-Side (a/b) Feature Variations
|
||||
|
||||
Note: this is a gloss / summary.
|
||||
|
||||
1. Your feature has a `startup` or `configuration` method that does different things depending on which variation is chosen.
|
||||
|
||||
1. Your feature has a `startup` or `configuration` method that does different things depending on which variation is chosen.
|
||||
|
||||
```javascript
|
||||
// bootstrap.js startup()...
|
||||
```javascript
|
||||
// bootstrap.js startup()...
|
||||
const variation = await studyUtils.deterministicVariation(myWeightedVariations);
|
||||
studyUtils.setVariation(variation);
|
||||
studyUtils.setVariation(variation);
|
||||
|
||||
//...
|
||||
//...
|
||||
|
||||
// start the feature
|
||||
TheFeature.startup(variation)
|
||||
```
|
||||
|
||||
2. Ensure that your Feature measures every variation, including the Control (no-effect).
|
||||
// start the feature
|
||||
TheFeature.startup(variation)
|
||||
```
|
||||
|
||||
2. Ensure that your Feature measures every variation, including the Control (no-effect).
|
||||
|
||||
## Kittens or Puppers, the Critical Study We have all been waiting for
|
||||
|
||||
Style:
|
||||
|
||||
- Embedded Web Extension
|
||||
- Telmetry on 'button click'
|
||||
- has one "end early" condition: 3 or more button presses during a sesson.
|
||||
- Goal: test if 'interest rate is higher for kittens or puppies, using a PROXY MEASURE -- "button clicks"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
* Embedded Web Extension
|
||||
* Telmetry on 'button click'
|
||||
* has one "end early" condition: 3 or more button presses during a sesson.
|
||||
* Goal: test if 'interest rate is higher for kittens or puppies, using a PROXY MEASURE -- "button clicks"
|
||||
|
||||
## Get More Help
|
||||
|
||||
- slack: `#shield`
|
||||
|
||||
|
||||
* slack: `#shield`
|
||||
|
||||
## Gotchas / FAQ / Ranting
|
||||
|
||||
### General
|
||||
|
||||
I am on Windows. How can I build?
|
||||
I am on Windows. How can I build?
|
||||
|
||||
- (see TODO link to the issue and instructions by JCrawford)
|
||||
* (see TODO link to the issue and instructions by JCrawford)
|
||||
|
||||
### studyUtils
|
||||
|
||||
|
||||
|
||||
### The lifecycle and deployment of the add-on once it gets released
|
||||
|
||||
The add-on for the experiment is remotely installed to the users which are selected for the experiment. (Note that this leads to an environment-change and a subsequent main ping)
|
||||
|
||||
Main telemetry is tagged with the user's currently running experiments so that the main telemetry data and shield ping data can be cross-referenced later.
|
||||
|
||||
After the experiment, the add-on is remotely uninstalled. In rare occasions, it remains installed until a new Firefox update is released.
|
||||
|
||||
Main telemetry is tagged with the user's currently running experiments so that the main telemetry data and shield ping data can be cross-referenced later.
|
||||
|
||||
After the experiment, the add-on is remotely uninstalled. In rare occasions, it remains installed until a new Firefox update is released.
|
||||
|
||||
### Legacy Addons
|
||||
|
||||
Debugging `Cu.import`.
|
||||
|
||||
- use `run-firefox` to 'try again' after any change to modules. "Reload addon" will probably not work.
|
||||
- Based on `chrome.manifest` files.
|
||||
- `chrome.manifest` paths can't have `@ # ; : ? /`
|
||||
- `chrome.manifest` isn't read yet in `bootstrap.js` main scope, OR during `install`. It is read during `startup` and `shutdown`
|
||||
- Remember to uninstall your modules.
|
||||
- [browser console][link-browser-console] will show errors sometimes.
|
||||
|
||||
* use `run-firefox` to 'try again' after any change to modules. "Reload addon" will probably not work.
|
||||
* Based on `chrome.manifest` files.
|
||||
* `chrome.manifest` paths can't have `@ # ; : ? /`
|
||||
* `chrome.manifest` isn't read yet in `bootstrap.js` main scope, OR during `install`. It is read during `startup` and `shutdown`
|
||||
* Remember to uninstall your modules.
|
||||
* [browser console][link-browser-console] will show errors sometimes.
|
||||
|
||||
### s.t.m.o - [sql.telemetry.mozilla.org](http://sql.telemetry.mozilla.org/)
|
||||
|
||||
|
||||
#### Where are my pings?
|
||||
|
||||
1. Are you seeing them in `about:telemetry` and / or the QA-Study-Helper. If YES, then they are being reported at client, good! If NO: check the config settings for your study for `telemetry.send => true`
|
||||
2. Is pref set weirdly: `toolkit.telemetry.server => https://incoming.telemetry.mozilla.org`. If you are running from `run_firefox` and maybe lots of other contexts, this pref will not be properly set (because we don’t usually want to send telemetry!) BAD RESULT: “toolkit.telemetry.server”, Pref::new(“https://%(server)s/dummy/telemetry/“))
|
||||
3. Have you waited… 3-5 minutes?
|
||||
1. Are you seeing them in `about:telemetry` and / or the QA-Study-Helper. If YES, then they are being reported at client, good! If NO: check the config settings for your study for `telemetry.send => true`
|
||||
2. Is pref set weirdly: `toolkit.telemetry.server => https://incoming.telemetry.mozilla.org`. If you are running from `run_firefox` and maybe lots of other contexts, this pref will not be properly set (because we don’t usually want to send telemetry!) BAD RESULT: “toolkit.telemetry.server”, Pref::new(“https://%(server)s/dummy/telemetry/“))
|
||||
3. Have you waited… 3-5 minutes?
|
||||
|
||||
|
||||
- All error messages are misleading. They almost always indicate issues with syntax. Sometimes they indicate mis-spelled fields.
|
||||
- No SEMI-COLONS at the end of your sql!
|
||||
- Athena >> Presto (10-20x faster!)
|
||||
- Be careful with single and double-quotes.
|
||||
* All error messages are misleading. They almost always indicate issues with syntax. Sometimes they indicate mis-spelled fields.
|
||||
* No SEMI-COLONS at the end of your sql!
|
||||
* Athena >> Presto (10-20x faster!)
|
||||
* Be careful with single and double-quotes.
|
||||
|
||||
## Glossary
|
||||
|
||||
- **Probe**. A Telemetry measure, or ping. More broadly: any measure sent anywhere.
|
||||
- **Variation**. synonyms (branch, arm):
|
||||
- which *specific* version / configuration a specific client is randomized into.
|
||||
- A JSON object describing the configuration for that specific choice, with keys like `name`.
|
||||
* **Probe**. A Telemetry measure, or ping. More broadly: any measure sent anywhere.
|
||||
* **Variation**. synonyms (branch, arm):
|
||||
* which _specific_ version / configuration a specific client is randomized into.
|
||||
* A JSON object describing the configuration for that specific choice, with keys like `name`.
|
||||
|
||||
## OTHER DOCS
|
||||
|
||||
- template/README.md
|
||||
|
||||
- should be edited for YOUR STUDY
|
||||
- move the general npm commands there
|
||||
- links to 'about shield stuides' (in general)
|
||||
- shield-study-addon-utils api
|
||||
* template/README.md
|
||||
|
||||
* should be edited for YOUR STUDY
|
||||
* move the general npm commands there
|
||||
* links to 'about shield stuides' (in general)
|
||||
* shield-study-addon-utils api
|
||||
|
||||
## `StudyUtils.jsm` api used in `bootstrap.js`
|
||||
|
||||
### Configuration
|
||||
|
||||
- `studyUtils.setup`
|
||||
* `studyUtils.setup`
|
||||
|
||||
Needed to send any telemetry
|
||||
Needed to send any telemetry
|
||||
|
||||
Minimal setup:
|
||||
|
||||
```
|
||||
{
|
||||
"studyName": "a-study-name",
|
||||
"endings": {},
|
||||
"telemetry": {
|
||||
"send": true, // assumed false. Actually send pings?
|
||||
"removeTestingFlag": false, // Marks pings as testing, set true for actual release
|
||||
}
|
||||
}
|
||||
```
|
||||
Minimal setup:
|
||||
|
||||
```
|
||||
{
|
||||
"studyName": "a-study-name",
|
||||
"endings": {},
|
||||
"telemetry": {
|
||||
"send": true, // assumed false. Actually send pings?
|
||||
"removeTestingFlag": false, // Marks pings as testing, set true for actual release
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `studyUtils.deterministicVariation(weightedVariations)`
|
||||
|
||||
Suggest a variation.
|
||||
Suggest a variation.
|
||||
|
||||
- `studyUtils.setVariation(anObjectWithNameKey)`
|
||||
|
||||
Actually set the variation.
|
||||
|
||||
Actually set the variation.
|
||||
|
||||
### Lifecycle
|
||||
|
||||
- `studyUtils.firstSeen()`
|
||||
* `studyUtils.firstSeen()`
|
||||
|
||||
- Send the `enter` ping.
|
||||
- Future: Record first entry.
|
||||
* Send the `enter` ping.
|
||||
* Future: Record first entry.
|
||||
|
||||
- `await studyUtils.startup({reason})`
|
||||
* `await studyUtils.startup({reason})`
|
||||
|
||||
If 'install', send an install ping.
|
||||
If 'install', send an install ping.
|
||||
|
||||
- `studyUtils.endStudy(endingName)`;
|
||||
|
||||
- Send ending ping
|
||||
- Open a url for that ending if defined
|
||||
- Uninstalls addon
|
||||
* `studyUtils.endStudy(endingName)`;
|
||||
|
||||
* Send ending ping
|
||||
* Open a url for that ending if defined
|
||||
* Uninstalls addon
|
||||
|
||||
### Running
|
||||
|
||||
- `await studyUtils.info()`
|
||||
* `await studyUtils.info()`
|
||||
|
||||
Return configuration info
|
||||
Return configuration info
|
||||
|
||||
- `studyUtils.respondToWebExtensionMessage`
|
||||
* `studyUtils.respondToWebExtensionMessage`
|
||||
|
||||
"Do shield things" (`telemetry`, `info`, `endStudy`)
|
||||
"Do shield things" (`telemetry`, `info`, `endStudy`)
|
||||
|
||||
- `studyUtils._isEnding`
|
||||
* `studyUtils._isEnding`
|
||||
|
||||
Useful flag for knowing if something is already calling an ending, to help prevent race conditions and "double endings"
|
||||
|
||||
- `studyUtils.telemetry(stringStringObject)`
|
||||
|
||||
Send a 'study specific' ping to `shield-study-addon` bucket.
|
||||
Useful flag for knowing if something is already calling an ending, to help prevent race conditions and "double endings"
|
||||
|
||||
* `studyUtils.telemetry(stringStringObject)`
|
||||
|
||||
Send a 'study specific' ping to `shield-study-addon` bucket.
|
||||
|
||||
### TODO
|
||||
|
||||
Change SSAU api to this:
|
||||
|
||||
- suggestVariation
|
||||
- setup(includes branch)
|
||||
- install() => firstSeen() => ping('enter');
|
||||
-
|
||||
- alreadyEnding()
|
||||
- endStudy()? tryEndStudy()? # first in.
|
||||
|
||||
- info
|
||||
- respondToWebExtension / respond?
|
||||
- telemetry
|
||||
* suggestVariation
|
||||
* setup(includes branch)
|
||||
* install() => firstSeen() => ping('enter');
|
||||
*
|
||||
* alreadyEnding()
|
||||
* endStudy()? tryEndStudy()? # first in.
|
||||
|
||||
* info
|
||||
* respondToWebExtension / respond?
|
||||
* telemetry
|
||||
|
||||
## FIXES
|
||||
|
||||
|
@ -641,7 +607,6 @@ startup(reason) {
|
|||
if INSTALL, then send install
|
||||
else send nothing
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
@ -658,25 +623,22 @@ endStudy
|
|||
endStudy()
|
||||
|
||||
telemetry();
|
||||
|
||||
```
|
||||
|
||||
## TODO
|
||||
|
||||
- debuggin and setting localstore? Prefs are 1000x easier
|
||||
- debug both halves.
|
||||
|
||||
* debuggin and setting localstore? Prefs are 1000x easier
|
||||
* debug both halves.
|
||||
|
||||
## Template
|
||||
|
||||
- see the cloneable template HERE
|
||||
- see some other examples HERE
|
||||
* see the cloneable template HERE
|
||||
* see some other examples HERE
|
||||
|
||||
if at template...
|
||||
say
|
||||
Acutally, read the docs at SSAU there.
|
||||
|
||||
|
||||
## Getting QA of your addons
|
||||
|
||||
https://mana.mozilla.org/wiki/display/PI/PI+Request
|
||||
|
@ -684,18 +646,12 @@ https://mana.mozilla.org/wiki/display/PI/PI+Request
|
|||
## Links and References
|
||||
|
||||
[link-browser-console]: https://developer.mozilla.org/en-US/docs/Tools/Browser_Console
|
||||
|
||||
[link-legacy]: https://developer.mozilla.org/en-US/Add-ons/Legacy_add_ons
|
||||
|
||||
|
||||
[link-webextensions]: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples
|
||||
|
||||
[link-legacy]: https://developer.mozilla.org/en-US/Add-ons/Legacy_add_ons
|
||||
[link-webextensions]: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples
|
||||
[link-embedded]: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Embedded_WebExtensions
|
||||
|
||||
[stmo-study-states]: https://sql.telemetry.mozilla.org/queries/47604/source#table
|
||||
|
||||
[qa-helper-addon-direct]: https://bugzilla.mozilla.org/attachment.cgi?id=8917534
|
||||
|
||||
[legacy-signing]: see TODO link
|
||||
[legacy-signing]: see TODO link
|
||||
|
||||
[mozilla-ssau]: https://github.com/mozilla/shield-studies-addon-utils
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
Surviving on shield island
|
||||
|
||||
You are a wizened and skillful dev. Perhaps you have built a 99.99% uptime website serving millions of users, or you built the firefox awesomebar.... but can you SURVIVE SHIELD ISLAND?
|
||||
You are a wizened and skillful dev. Perhaps you have built a 99.99% uptime website serving millions of users, or you built the firefox awesomebar.... but can you SURVIVE SHIELD ISLAND?
|
||||
|
||||
> Inventory
|
||||
|
||||
- Firefox nightly, firefox beta, firefox (release)
|
||||
- npm
|
||||
- git / github
|
||||
- shield-studies-addon-utils (studyUtils.jsm)
|
||||
|
||||
* Firefox nightly, firefox beta, firefox (release)
|
||||
* npm
|
||||
* git / github
|
||||
* shield-studies-addon-utils (studyUtils.jsm)
|
||||
|
||||
> Look
|
||||
|
||||
|
@ -27,8 +26,9 @@ StudyUtils.jsm worn.
|
|||
You feel optimistic, despite the long odds of survival.
|
||||
|
||||
You can:
|
||||
- TELEMETRY: send well-formatted probes
|
||||
- SETVARIATION: use the studyName and Telemetry client to consistently and determistically to assign the client to a particular branch
|
||||
|
||||
* TELEMETRY: send well-formatted probes
|
||||
* SETVARIATION: use the studyName and Telemetry client to consistently and determistically to assign the client to a particular branch
|
||||
|
||||
(see TODO)
|
||||
|
||||
|
@ -36,17 +36,12 @@ You can:
|
|||
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
> examine dark clouds
|
||||
|
||||
As you look up, a light rain starts to fall. You wonder how you will make a fire to keep warm, as your clothes start to soak. The first chills of hypothermia ripple your flesh.
|
||||
As you look up, a light rain starts to fall. You wonder how you will make a fire to keep warm, as your clothes start to soak. The first chills of hypothermia ripple your flesh.
|
||||
|
||||
Legacy addon development has challenges.
|
||||
|
||||
|
||||
> examine handbook.
|
||||
|
||||
(taking handbook)
|
||||
|
@ -61,41 +56,36 @@ Get DATA to Telemetry
|
|||
About user actions
|
||||
so that you can make decisions about WHICH APPROACH.
|
||||
|
||||
|
||||
## Telemetry First Development
|
||||
|
||||
Everything in a SHIELD STUDY leads to allowing ANALYSTS to get data quickly, reliably, and consistently so that they can do analysis of this form:
|
||||
|
||||
- for Which VARIATION of a feature
|
||||
- did users 'do best'.
|
||||
* for Which VARIATION of a feature
|
||||
* did users 'do best'.
|
||||
|
||||
Your SHIELD-STUDY Legacy Addon is a DELIVERY MECHANISM to collect that data.
|
||||
|
||||
|
||||
An example analysis table
|
||||
|
||||
An exmple telemetry `shield-study-addon` probe that contributes to that.
|
||||
|
||||
Here is the SQL.
|
||||
|
||||
|
||||
## An EMPTY STUDY.
|
||||
|
||||
> use flint and steel to make fire
|
||||
|
||||
## Do I
|
||||
|
||||
|
||||
|
||||
## But I like making User Interface?
|
||||
|
||||
Don't we all?! Mocks are fun! Styling is fun!
|
||||
Don't we all?! Mocks are fun! Styling is fun!
|
||||
|
||||
starting with Telemetry makes soe of the... unexpected decisions make sense.
|
||||
|
||||
## Wait, did you say legacy addon?
|
||||
|
||||
Yes. Web Extensions CAN'T SEND TELEMETRY. We need Firefox (chrome) privileges to access the `TelemetryController.jsm`. That meanss
|
||||
Yes. Web Extensions CAN'T SEND TELEMETRY. We need Firefox (chrome) privileges to access the `TelemetryController.jsm`. That meanss
|
||||
|
||||
> make webExtension
|
||||
|
||||
|
@ -103,16 +93,17 @@ Good idea, for some UI's.
|
|||
|
||||
## But I have been buildling UI in pure Legacy Extensions since Firefox 2.
|
||||
|
||||
Awesome work! Firebug was awesome. You have no further use of this guide, and should go to [TODO:Shield-Studies-Addon-Utils-api.md].
|
||||
Awesome work! Firebug was awesome. You have no further use of this guide, and should go to [TODO:Shield-Studies-Addon-Utils-api.md].
|
||||
|
||||
## Tools and inventory
|
||||
|
||||
### > x template
|
||||
|
||||
We have a template folder at TODO:template. The files are...
|
||||
We have a template folder at TODO:template. The files are...
|
||||
|
||||
The template shows an EMBEDDED WEB EXTENSION with
|
||||
- build scripts
|
||||
|
||||
* build scripts
|
||||
|
||||
```
|
||||
the file tree
|
||||
|
@ -120,16 +111,14 @@ the file tree
|
|||
|
||||
## Part 1, instrumenting buttons in an embedded web extension.
|
||||
|
||||
|
||||
### Action and Probes
|
||||
|
||||
Pretend story: which of several buttons is the most compelling to firefox users.
|
||||
Pretend story: which of several buttons is the most compelling to firefox users.
|
||||
|
||||
Good news: probes are mostly plain-old-javascrpt-objects.
|
||||
Good news: probes are mostly plain-old-javascrpt-objects.
|
||||
|
||||
Back news, getting
|
||||
|
||||
|
||||
### side-by-side deployment
|
||||
|
||||
### building 2 buttons.
|
||||
|
@ -140,34 +129,18 @@ This part is EASY using the webExtension
|
|||
|
||||
Getting the probes to firefox
|
||||
|
||||
|
||||
|
||||
"At least both branches are equally bad": A plea for experimental controls
|
||||
|
||||
"At least both branches are equally bad": A plea for experimental controls
|
||||
|
||||
FInding shelter
|
||||
|
||||
Send message / signal mirror / telemetry?
|
||||
|
||||
|
||||
> go woods
|
||||
|
||||
A monkey appears. It is curious about you
|
||||
A monkey appears. It is curious about you
|
||||
|
||||
(Helper addon for QA telemetry)
|
||||
|
||||
|
||||
|
||||
|
||||
## Full List of All Shield Telemetry Spoilers
|
||||
|
||||
|
||||
|
||||
|
||||
## Shield Study Utils Api
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
# Tutorial Study: Fake button study.
|
||||
|
||||
# Tutorial Study: Fake button study.
|
||||
|
||||
Learner goals:
|
||||
1. build a shield-instrumented Embedded Web Extension
|
||||
2. understand how probes, analysis, code relate
|
||||
|
||||
1. build a shield-instrumented Embedded Web Extension
|
||||
2. understand how probes, analysis, code relate
|
||||
|
||||
Concepts:
|
||||
- technical terms
|
||||
- web extension
|
||||
- embedded web extension
|
||||
- Legacy (bootstrap) addon
|
||||
- debugging techniques
|
||||
- `web-ext`
|
||||
- `about:debugging`
|
||||
- `run-firefox.js`
|
||||
|
||||
* technical terms
|
||||
* web extension
|
||||
* embedded web extension
|
||||
* Legacy (bootstrap) addon
|
||||
* debugging techniques
|
||||
* `web-ext`
|
||||
* `about:debugging`
|
||||
* `run-firefox.js`
|
||||
|
||||
## Questions?
|
||||
|
||||
- start from empty dir, or from the finished project?
|
||||
- how much to build in the first step.
|
||||
- how to display the order of the steps?
|
||||
* start from empty dir, or from the finished project?
|
||||
* how much to build in the first step.
|
||||
* how to display the order of the steps?
|
||||
|
||||
(Steps, order unclear)
|
||||
|
||||
|
@ -49,10 +48,10 @@ Plumb the listener
|
|||
|
||||
### incorporating shield to listen
|
||||
|
||||
- PERMANENT Randomization, revisited.
|
||||
- Telemetry sending
|
||||
- debugging
|
||||
- helper addon
|
||||
* PERMANENT Randomization, revisited.
|
||||
* Telemetry sending
|
||||
* debugging
|
||||
* helper addon
|
||||
|
||||
## Advanced
|
||||
|
||||
|
@ -60,12 +59,9 @@ Plumb the listener
|
|||
|
||||
## good probes
|
||||
|
||||
- good probes mirror the analysis.
|
||||
- Analysis wants to be sql. Try to make the probes reflect that.
|
||||
* good probes mirror the analysis.
|
||||
* Analysis wants to be sql. Try to make the probes reflect that.
|
||||
|
||||
## Why Shield-Utils?
|
||||
|
||||
## surveys?
|
||||
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче