sfdx-browserforce-plugin 5.1.1 → 5.2.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -16
- package/lib/browserforce-command.d.ts +15 -0
- package/lib/browserforce-command.js +61 -0
- package/lib/browserforce-command.js.map +1 -0
- package/lib/browserforce.d.ts +29 -0
- package/lib/browserforce.js +194 -0
- package/lib/browserforce.js.map +1 -0
- package/lib/commands/browserforce/apply.d.ts +10 -0
- package/lib/commands/browserforce/apply.js +54 -0
- package/lib/commands/browserforce/apply.js.map +1 -0
- package/lib/commands/browserforce/plan.d.ts +10 -0
- package/lib/commands/browserforce/plan.js +56 -0
- package/lib/commands/browserforce/plan.js.map +1 -0
- package/lib/config-parser.d.ts +16 -0
- package/lib/config-parser.js +24 -0
- package/lib/config-parser.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -0
- package/lib/jsforce-utils.d.ts +5 -0
- package/lib/jsforce-utils.js +14 -0
- package/lib/jsforce-utils.js.map +1 -0
- package/lib/pages/login.d.ts +8 -0
- package/lib/pages/login.js +39 -0
- package/lib/pages/login.js.map +1 -0
- package/lib/plugin.d.ts +17 -0
- package/lib/plugin.js +30 -0
- package/lib/plugin.js.map +1 -0
- package/lib/plugins/activity-settings/index.d.ts +9 -0
- package/lib/plugins/activity-settings/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/activity-settings/index.e2e-spec.js +36 -0
- package/lib/plugins/activity-settings/index.e2e-spec.js.map +1 -0
- package/lib/plugins/activity-settings/index.js +34 -0
- package/lib/plugins/activity-settings/index.js.map +1 -0
- package/lib/plugins/company-information/index.d.ts +8 -0
- package/lib/plugins/company-information/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/company-information/index.e2e-spec.js +37 -0
- package/lib/plugins/company-information/index.e2e-spec.js.map +1 -0
- package/lib/plugins/company-information/index.js +60 -0
- package/lib/plugins/company-information/index.js.map +1 -0
- package/lib/plugins/customer-portal/available-custom-objects/index.d.ts +14 -0
- package/lib/plugins/customer-portal/available-custom-objects/index.js +114 -0
- package/lib/plugins/customer-portal/available-custom-objects/index.js.map +1 -0
- package/lib/plugins/customer-portal/available-custom-objects/index.test.d.ts +1 -0
- package/lib/plugins/customer-portal/available-custom-objects/index.test.js +39 -0
- package/lib/plugins/customer-portal/available-custom-objects/index.test.js.map +1 -0
- package/lib/plugins/customer-portal/enabled/index.d.ts +6 -0
- package/lib/plugins/customer-portal/enabled/index.js +26 -0
- package/lib/plugins/customer-portal/enabled/index.js.map +1 -0
- package/lib/plugins/customer-portal/enabled/index.test.d.ts +1 -0
- package/lib/plugins/customer-portal/enabled/index.test.js +34 -0
- package/lib/plugins/customer-portal/enabled/index.test.js.map +1 -0
- package/lib/plugins/customer-portal/index.d.ts +15 -0
- package/lib/plugins/customer-portal/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/customer-portal/index.e2e-spec.js +202 -0
- package/lib/plugins/customer-portal/index.e2e-spec.js.map +1 -0
- package/lib/plugins/customer-portal/index.js +59 -0
- package/lib/plugins/customer-portal/index.js.map +1 -0
- package/lib/plugins/customer-portal/index.test.d.ts +1 -0
- package/lib/plugins/customer-portal/index.test.js +84 -0
- package/lib/plugins/customer-portal/index.test.js.map +1 -0
- package/lib/plugins/customer-portal/portals/index.d.ts +25 -0
- package/lib/plugins/customer-portal/portals/index.js +216 -0
- package/lib/plugins/customer-portal/portals/index.js.map +1 -0
- package/lib/plugins/customer-portal/portals/index.test.d.ts +1 -0
- package/lib/plugins/customer-portal/portals/index.test.js +140 -0
- package/lib/plugins/customer-portal/portals/index.test.js.map +1 -0
- package/lib/plugins/density-settings/index.d.ts +10 -0
- package/lib/plugins/density-settings/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/density-settings/index.e2e-spec.js +39 -0
- package/lib/plugins/density-settings/index.e2e-spec.js.map +1 -0
- package/lib/plugins/density-settings/index.js +54 -0
- package/lib/plugins/density-settings/index.js.map +1 -0
- package/lib/plugins/deprecated.d.ts +4 -0
- package/lib/plugins/deprecated.js +28 -0
- package/lib/plugins/deprecated.js.map +1 -0
- package/lib/plugins/email-deliverability/index.d.ts +9 -0
- package/lib/plugins/email-deliverability/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/email-deliverability/index.e2e-spec.js +55 -0
- package/lib/plugins/email-deliverability/index.e2e-spec.js.map +1 -0
- package/lib/plugins/email-deliverability/index.js +42 -0
- package/lib/plugins/email-deliverability/index.js.map +1 -0
- package/lib/plugins/high-velocity-sales-settings/index.d.ts +10 -0
- package/lib/plugins/high-velocity-sales-settings/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/high-velocity-sales-settings/index.e2e-spec.js +29 -0
- package/lib/plugins/high-velocity-sales-settings/index.e2e-spec.js.map +1 -0
- package/lib/plugins/high-velocity-sales-settings/index.js +42 -0
- package/lib/plugins/high-velocity-sales-settings/index.js.map +1 -0
- package/lib/plugins/high-velocity-sales-settings/page.d.ts +7 -0
- package/lib/plugins/high-velocity-sales-settings/page.js +28 -0
- package/lib/plugins/high-velocity-sales-settings/page.js.map +1 -0
- package/lib/plugins/history-tracking/index.d.ts +17 -0
- package/lib/plugins/history-tracking/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/history-tracking/index.e2e-spec.js +106 -0
- package/lib/plugins/history-tracking/index.e2e-spec.js.map +1 -0
- package/lib/plugins/history-tracking/index.js +176 -0
- package/lib/plugins/history-tracking/index.js.map +1 -0
- package/lib/plugins/home-page-layouts/index.d.ts +14 -0
- package/lib/plugins/home-page-layouts/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/home-page-layouts/index.e2e-spec.js +47 -0
- package/lib/plugins/home-page-layouts/index.e2e-spec.js.map +1 -0
- package/lib/plugins/home-page-layouts/index.js +94 -0
- package/lib/plugins/home-page-layouts/index.js.map +1 -0
- package/lib/plugins/home-page-layouts/index.test.d.ts +1 -0
- package/lib/plugins/home-page-layouts/index.test.js +104 -0
- package/lib/plugins/home-page-layouts/index.test.js.map +1 -0
- package/lib/plugins/index.d.ts +24 -0
- package/lib/plugins/index.js +25 -0
- package/lib/plugins/index.js.map +1 -0
- package/lib/plugins/lightning-experience-settings/index.d.ts +18 -0
- package/lib/plugins/lightning-experience-settings/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/lightning-experience-settings/index.e2e-spec.js +40 -0
- package/lib/plugins/lightning-experience-settings/index.e2e-spec.js.map +1 -0
- package/lib/plugins/lightning-experience-settings/index.js +101 -0
- package/lib/plugins/lightning-experience-settings/index.js.map +1 -0
- package/lib/plugins/linkedin-sales-navigator-settings/index.d.ts +8 -0
- package/lib/plugins/linkedin-sales-navigator-settings/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/linkedin-sales-navigator-settings/index.e2e-spec.js +29 -0
- package/lib/plugins/linkedin-sales-navigator-settings/index.e2e-spec.js.map +1 -0
- package/lib/plugins/linkedin-sales-navigator-settings/index.js +15 -0
- package/lib/plugins/linkedin-sales-navigator-settings/index.js.map +1 -0
- package/lib/plugins/linkedin-sales-navigator-settings/page.d.ts +10 -0
- package/lib/plugins/linkedin-sales-navigator-settings/page.js +42 -0
- package/lib/plugins/linkedin-sales-navigator-settings/page.js.map +1 -0
- package/lib/plugins/omni-channel-settings/index.d.ts +9 -0
- package/lib/plugins/omni-channel-settings/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/omni-channel-settings/index.e2e-spec.js +30 -0
- package/lib/plugins/omni-channel-settings/index.e2e-spec.js.map +1 -0
- package/lib/plugins/omni-channel-settings/index.js +21 -0
- package/lib/plugins/omni-channel-settings/index.js.map +1 -0
- package/lib/plugins/opportunity-splits/index.d.ts +9 -0
- package/lib/plugins/opportunity-splits/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/opportunity-splits/index.e2e-spec.js +46 -0
- package/lib/plugins/opportunity-splits/index.e2e-spec.js.map +1 -0
- package/lib/plugins/opportunity-splits/index.js +32 -0
- package/lib/plugins/opportunity-splits/index.js.map +1 -0
- package/lib/plugins/opportunity-splits/pages/layout-selection.d.ts +8 -0
- package/lib/plugins/opportunity-splits/pages/layout-selection.js +15 -0
- package/lib/plugins/opportunity-splits/pages/layout-selection.js.map +1 -0
- package/lib/plugins/opportunity-splits/pages/overview.d.ts +10 -0
- package/lib/plugins/opportunity-splits/pages/overview.js +33 -0
- package/lib/plugins/opportunity-splits/pages/overview.js.map +1 -0
- package/lib/plugins/opportunity-splits/pages/setup.d.ts +8 -0
- package/lib/plugins/opportunity-splits/pages/setup.js +17 -0
- package/lib/plugins/opportunity-splits/pages/setup.js.map +1 -0
- package/lib/plugins/permission-sets/index.d.ts +10 -0
- package/lib/plugins/permission-sets/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/permission-sets/index.e2e-spec.js +47 -0
- package/lib/plugins/permission-sets/index.e2e-spec.js.map +1 -0
- package/lib/plugins/permission-sets/index.js +22 -0
- package/lib/plugins/permission-sets/index.js.map +1 -0
- package/lib/plugins/permission-sets/service-presence-status/index.d.ts +10 -0
- package/lib/plugins/permission-sets/service-presence-status/index.js +67 -0
- package/lib/plugins/permission-sets/service-presence-status/index.js.map +1 -0
- package/lib/plugins/picklists/field-dependencies/index.d.ts +11 -0
- package/lib/plugins/picklists/field-dependencies/index.js +56 -0
- package/lib/plugins/picklists/field-dependencies/index.js.map +1 -0
- package/lib/plugins/picklists/field-dependencies/index.test.d.ts +1 -0
- package/lib/plugins/picklists/field-dependencies/index.test.js +64 -0
- package/lib/plugins/picklists/field-dependencies/index.test.js.map +1 -0
- package/lib/plugins/picklists/field-dependencies/pages.d.ts +14 -0
- package/lib/plugins/picklists/field-dependencies/pages.js +49 -0
- package/lib/plugins/picklists/field-dependencies/pages.js.map +1 -0
- package/lib/plugins/picklists/index.d.ts +23 -0
- package/lib/plugins/picklists/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/picklists/index.e2e-spec.js +100 -0
- package/lib/plugins/picklists/index.e2e-spec.js.map +1 -0
- package/lib/plugins/picklists/index.js +153 -0
- package/lib/plugins/picklists/index.js.map +1 -0
- package/lib/plugins/picklists/pages.d.ts +41 -0
- package/lib/plugins/picklists/pages.js +166 -0
- package/lib/plugins/picklists/pages.js.map +1 -0
- package/lib/plugins/picklists/standard-value-set.d.ts +1 -0
- package/lib/plugins/picklists/standard-value-set.js +80 -0
- package/lib/plugins/picklists/standard-value-set.js.map +1 -0
- package/lib/plugins/record-types/index.d.ts +13 -0
- package/lib/plugins/record-types/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/record-types/index.e2e-spec.js +73 -0
- package/lib/plugins/record-types/index.e2e-spec.js.map +1 -0
- package/lib/plugins/record-types/index.js +70 -0
- package/lib/plugins/record-types/index.js.map +1 -0
- package/lib/plugins/record-types/pages.d.ts +15 -0
- package/lib/plugins/record-types/pages.js +56 -0
- package/lib/plugins/record-types/pages.js.map +1 -0
- package/lib/plugins/relate-contact-to-multiple-accounts/index.d.ts +11 -0
- package/lib/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.js +29 -0
- package/lib/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.js.map +1 -0
- package/lib/plugins/relate-contact-to-multiple-accounts/index.js +62 -0
- package/lib/plugins/relate-contact-to-multiple-accounts/index.js.map +1 -0
- package/lib/plugins/reports-and-dashboards/folder-sharing/index.d.ts +8 -0
- package/lib/plugins/reports-and-dashboards/folder-sharing/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/reports-and-dashboards/folder-sharing/index.e2e-spec.js +3 -0
- package/lib/plugins/reports-and-dashboards/folder-sharing/index.e2e-spec.js.map +1 -0
- package/lib/plugins/reports-and-dashboards/folder-sharing/index.js +55 -0
- package/lib/plugins/reports-and-dashboards/folder-sharing/index.js.map +1 -0
- package/lib/plugins/reports-and-dashboards/index.d.ts +11 -0
- package/lib/plugins/reports-and-dashboards/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/reports-and-dashboards/index.e2e-spec.js +3 -0
- package/lib/plugins/reports-and-dashboards/index.e2e-spec.js.map +1 -0
- package/lib/plugins/reports-and-dashboards/index.js +29 -0
- package/lib/plugins/reports-and-dashboards/index.js.map +1 -0
- package/lib/plugins/salesforce-cpq-config/formConfig.d.ts +17 -0
- package/lib/plugins/salesforce-cpq-config/formConfig.js +649 -0
- package/lib/plugins/salesforce-cpq-config/formConfig.js.map +1 -0
- package/lib/plugins/salesforce-cpq-config/index.d.ts +7 -0
- package/lib/plugins/salesforce-cpq-config/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/salesforce-cpq-config/index.e2e-spec.js +37 -0
- package/lib/plugins/salesforce-cpq-config/index.e2e-spec.js.map +1 -0
- package/lib/plugins/salesforce-cpq-config/index.js +214 -0
- package/lib/plugins/salesforce-cpq-config/index.js.map +1 -0
- package/lib/plugins/salesforce-to-salesforce/index.d.ts +9 -0
- package/lib/plugins/salesforce-to-salesforce/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/salesforce-to-salesforce/index.e2e-spec.js +35 -0
- package/lib/plugins/salesforce-to-salesforce/index.e2e-spec.js.map +1 -0
- package/lib/plugins/salesforce-to-salesforce/index.js +36 -0
- package/lib/plugins/salesforce-to-salesforce/index.js.map +1 -0
- package/lib/plugins/security/authentication-configuration/index.d.ts +11 -0
- package/lib/plugins/security/authentication-configuration/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/security/authentication-configuration/index.e2e-spec.js +101 -0
- package/lib/plugins/security/authentication-configuration/index.e2e-spec.js.map +1 -0
- package/lib/plugins/security/authentication-configuration/index.js +67 -0
- package/lib/plugins/security/authentication-configuration/index.js.map +1 -0
- package/lib/plugins/security/certificate-and-key-management/index.d.ts +23 -0
- package/lib/plugins/security/certificate-and-key-management/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/security/certificate-and-key-management/index.e2e-spec.js +63 -0
- package/lib/plugins/security/certificate-and-key-management/index.e2e-spec.js.map +1 -0
- package/lib/plugins/security/certificate-and-key-management/index.js +154 -0
- package/lib/plugins/security/certificate-and-key-management/index.js.map +1 -0
- package/lib/plugins/security/certificate-and-key-management/index.test.d.ts +1 -0
- package/lib/plugins/security/certificate-and-key-management/index.test.js +61 -0
- package/lib/plugins/security/certificate-and-key-management/index.test.js.map +1 -0
- package/lib/plugins/security/index.d.ts +13 -0
- package/lib/plugins/security/index.js +42 -0
- package/lib/plugins/security/index.js.map +1 -0
- package/lib/plugins/service-channels/capacity/index.d.ts +18 -0
- package/lib/plugins/service-channels/capacity/index.js +162 -0
- package/lib/plugins/service-channels/capacity/index.js.map +1 -0
- package/lib/plugins/service-channels/index.d.ts +12 -0
- package/lib/plugins/service-channels/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/service-channels/index.e2e-spec.js +61 -0
- package/lib/plugins/service-channels/index.e2e-spec.js.map +1 -0
- package/lib/plugins/service-channels/index.js +38 -0
- package/lib/plugins/service-channels/index.js.map +1 -0
- package/lib/plugins/slack/index.d.ts +9 -0
- package/lib/plugins/slack/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/slack/index.e2e-spec.js +47 -0
- package/lib/plugins/slack/index.e2e-spec.js.map +1 -0
- package/lib/plugins/slack/index.js +46 -0
- package/lib/plugins/slack/index.js.map +1 -0
- package/lib/plugins/user-access-policies/index.d.ts +19 -0
- package/lib/plugins/user-access-policies/index.e2e-spec.d.ts +1 -0
- package/lib/plugins/user-access-policies/index.e2e-spec.js +63 -0
- package/lib/plugins/user-access-policies/index.e2e-spec.js.map +1 -0
- package/lib/plugins/user-access-policies/index.js +107 -0
- package/lib/plugins/user-access-policies/index.js.map +1 -0
- package/lib/plugins/user-access-policies/page.d.ts +29 -0
- package/lib/plugins/user-access-policies/page.js +115 -0
- package/lib/plugins/user-access-policies/page.js.map +1 -0
- package/lib/plugins/utils.d.ts +3 -0
- package/lib/plugins/utils.js +47 -0
- package/lib/plugins/utils.js.map +1 -0
- package/oclif.manifest.json +153 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ $ sf browserforce apply -f ./config/currency.json --target-org myOrg@example.com
|
|
|
54
54
|
|
|
55
55
|
- 🔧 configuration using JSON Schema (similar to the [Scratch Org Definition Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file.htm))
|
|
56
56
|
- 🧠 idempotency of the `apply` command only applies what's necessary and allows re-execution (concept similar to [terraform](https://www.terraform.io/docs/commands/apply.html))
|
|
57
|
-
- 🏎️ browser automation powered by
|
|
57
|
+
- 🏎️ browser automation powered by Playwright, [learn more about Playwright and Browserforce](#playwright)
|
|
58
58
|
|
|
59
59
|
# Supported Browserforce Settings
|
|
60
60
|
|
|
@@ -126,30 +126,68 @@ Both the `browserforce apply` and `browserforce plan` commands expect a config f
|
|
|
126
126
|
- `BROWSERFORCE_RETRY_MAX_RETRIES`: number of retries on failures opening a page (default: `4`)
|
|
127
127
|
- `BROWSERFORCE_RETRY_TIMEOUT_MS`: initial time between retries in exponential mode (default: `4000`)
|
|
128
128
|
|
|
129
|
-
#
|
|
129
|
+
# Migration to Playwright
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
**Important Notice for Next Version Release:**
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
This project is transitioning from Puppeteer to Playwright for browser automation. The migration is planned for the next major version release.
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
> [Chrome for Testing](https://goo.gle/chrome-for-testing) (~170MB macOS, ~282MB Linux, ~280MB Windows) that is [guaranteed to
|
|
137
|
-
> work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy)
|
|
138
|
-
> with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder
|
|
139
|
-
> by default (starting with Puppeteer v19.0.0).
|
|
135
|
+
## What This Means for Users
|
|
140
136
|
|
|
141
|
-
|
|
137
|
+
### Current Version (Puppeteer-based)
|
|
138
|
+
- Continues to work as expected
|
|
139
|
+
- No action required from users
|
|
140
|
+
- Maintained for stability
|
|
142
141
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
142
|
+
### Next Version (Playwright-based)
|
|
143
|
+
The upcoming release will include:
|
|
144
|
+
|
|
145
|
+
1. **Improved Reliability**: Playwright offers better auto-waiting and more robust element interaction
|
|
146
|
+
2. **Better Frame Support**: Native iframe handling without workarounds
|
|
147
|
+
3. **Enhanced Debugging**: Built-in trace viewer and inspector tools
|
|
148
|
+
4. **Modern API**: More intuitive locator-based API
|
|
149
|
+
|
|
150
|
+
### Migration Actions Required
|
|
151
|
+
|
|
152
|
+
**For Plugin Developers:**
|
|
153
|
+
If you've created custom plugins or extended this project:
|
|
154
|
+
|
|
155
|
+
1. **Update Browser Automation Code**:
|
|
156
|
+
- Replace `page.$()` with `page.locator()`
|
|
157
|
+
- Replace `page.$$()` with `page.locator().all()`
|
|
158
|
+
- Update `ElementHandle` references to `Locator`
|
|
159
|
+
- Review frame handling code (Playwright has better native support)
|
|
160
|
+
|
|
161
|
+
2. **Update Dependencies**:
|
|
162
|
+
- Remove `puppeteer` dependency
|
|
163
|
+
- Add `playwright` or `@playwright/test` dependency
|
|
164
|
+
|
|
165
|
+
3. **Review Documentation**:
|
|
166
|
+
- See [`docs/PLAYWRIGHT.md`](docs/PLAYWRIGHT.md) for best practices
|
|
167
|
+
|
|
168
|
+
**For End Users:**
|
|
169
|
+
- No configuration changes required
|
|
170
|
+
- Browser download process remains similar
|
|
171
|
+
- Environment variables remain compatible
|
|
172
|
+
- All existing configuration files will continue to work
|
|
173
|
+
|
|
174
|
+
# Playwright
|
|
175
|
+
|
|
176
|
+
We use [Playwright](https://playwright.dev/) for browser automation which comes with its own Chromium browser.
|
|
177
|
+
|
|
178
|
+
The Playwright [installation guide](https://playwright.dev/docs/intro) describes how this works:
|
|
179
|
+
|
|
180
|
+
> Playwright comes with bundled browser binaries for Chromium, Firefox, and WebKit. When you install Playwright, it automatically downloads the Chromium browser to ensure consistent automation across different environments. The browser is downloaded to the OS-specific cache directory.
|
|
181
|
+
|
|
182
|
+
In most cases this just works! If you want to skip the download and use another browser installation, you can do this as follows:
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
For more information on browser automation best practices, see the [Playwright documentation](docs/PLAYWRIGHT.md).
|
|
149
186
|
|
|
150
187
|
Troubleshooting:
|
|
151
188
|
|
|
152
189
|
- The installation is triggered via the `postinstall` hook of npm/yarn. If you've disabled running scripts with npm (`--ignore-scripts` or via config file), it will not download the browser.
|
|
190
|
+
- If you encounter issues with browser downloads, you can manually install browsers with: `npx playwright install chromium`
|
|
153
191
|
|
|
154
192
|
# Contributing
|
|
155
193
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { Browserforce } from './browserforce.js';
|
|
3
|
+
export declare abstract class BrowserforceCommand<T> extends SfCommand<T> {
|
|
4
|
+
static baseFlags: {
|
|
5
|
+
'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
definitionfile: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
planfile: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
statefile: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
protected bf: Browserforce;
|
|
12
|
+
protected settings: any[];
|
|
13
|
+
init(): Promise<void>;
|
|
14
|
+
finally(err?: Error): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Flags, SfCommand, Ux } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { promises } from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { Browserforce } from './browserforce.js';
|
|
5
|
+
import { ConfigParser } from './config-parser.js';
|
|
6
|
+
import { handleDeprecations } from './plugins/deprecated.js';
|
|
7
|
+
import * as DRIVERS from './plugins/index.js';
|
|
8
|
+
export class BrowserforceCommand extends SfCommand {
|
|
9
|
+
static baseFlags = {
|
|
10
|
+
...SfCommand.baseFlags,
|
|
11
|
+
'target-org': Flags.requiredOrg(),
|
|
12
|
+
definitionfile: Flags.string({
|
|
13
|
+
char: 'f',
|
|
14
|
+
description: 'path to a browserforce state file',
|
|
15
|
+
}),
|
|
16
|
+
planfile: Flags.string({
|
|
17
|
+
char: 'p',
|
|
18
|
+
name: 'plan',
|
|
19
|
+
description: 'path to a browserforce plan file',
|
|
20
|
+
}),
|
|
21
|
+
statefile: Flags.string({
|
|
22
|
+
char: 's',
|
|
23
|
+
name: 'state',
|
|
24
|
+
description: 'path to a browserforce definition file\nThe schema is similar to the scratch org definition file.\nSee https://github.com/amtrack/sfdx-browserforce-plugin#supported-org-preferences for supported values.',
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
bf;
|
|
28
|
+
settings;
|
|
29
|
+
async init() {
|
|
30
|
+
await super.init();
|
|
31
|
+
const { flags } = await this.parse({
|
|
32
|
+
baseFlags: BrowserforceCommand.baseFlags,
|
|
33
|
+
});
|
|
34
|
+
let definition;
|
|
35
|
+
if (flags.definitionfile) {
|
|
36
|
+
const definitionFileData = await promises.readFile(path.resolve(flags.definitionfile), 'utf8');
|
|
37
|
+
try {
|
|
38
|
+
definition = JSON.parse(definitionFileData);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
throw new Error('Failed parsing definitionfile');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
handleDeprecations(definition);
|
|
45
|
+
// TODO: use require.resolve to dynamically load plugins from npm packages
|
|
46
|
+
this.settings = ConfigParser.parse(DRIVERS, definition);
|
|
47
|
+
this.bf = new Browserforce(flags['target-org'], new Ux({ jsonEnabled: this.jsonEnabled() }));
|
|
48
|
+
this.spinner.start('logging in');
|
|
49
|
+
await this.bf.login();
|
|
50
|
+
this.spinner.stop();
|
|
51
|
+
}
|
|
52
|
+
async finally(err) {
|
|
53
|
+
this.spinner.stop(err?.message);
|
|
54
|
+
if (this.bf) {
|
|
55
|
+
this.spinner.start('logging out');
|
|
56
|
+
await this.bf.logout();
|
|
57
|
+
this.spinner.stop();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=browserforce-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browserforce-command.js","sourceRoot":"","sources":["../src/browserforce-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAE9C,MAAM,OAAgB,mBAAuB,SAAQ,SAAY;IAC/D,MAAM,CAAC,SAAS,GAAG;QACjB,GAAG,SAAS,CAAC,SAAS;QACtB,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE;QACjC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,mCAAmC;SACjD,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,kCAAkC;SAChD,CAAC;QACF,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;YACtB,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,OAAO;YACb,WAAW,EACT,4MAA4M;SAC/M,CAAC;KACH,CAAC;IACQ,EAAE,CAAe;IACjB,QAAQ,CAAQ;IAEnB,KAAK,CAAC,IAAI;QACf,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;YACjC,SAAS,EAAE,mBAAmB,CAAC,SAAS;SACzC,CAAC,CAAC;QACH,IAAI,UAAU,CAAC;QACf,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,kBAAkB,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAChD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAClC,MAAM,CACP,CAAC;YACF,IAAI,CAAC;gBACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAC/B,0EAA0E;QAC1E,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE,GAAG,IAAI,YAAY,CACxB,KAAK,CAAC,YAAY,CAAC,EACnB,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAC5C,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjC,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAW;QAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAClC,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Org } from '@salesforce/core';
|
|
2
|
+
import { type Ux } from '@salesforce/sf-plugins-core';
|
|
3
|
+
import { Browser, BrowserContext, Page, FrameLocator } from 'playwright';
|
|
4
|
+
export declare class Browserforce {
|
|
5
|
+
org: Org;
|
|
6
|
+
logger?: Ux;
|
|
7
|
+
browser: Browser;
|
|
8
|
+
context: BrowserContext;
|
|
9
|
+
page: Page;
|
|
10
|
+
lightningSetupUrl: string;
|
|
11
|
+
constructor(org: Org, logger?: Ux);
|
|
12
|
+
login(): Promise<Browserforce>;
|
|
13
|
+
logout(): Promise<Browserforce>;
|
|
14
|
+
throwPageErrors(page: Page): Promise<void>;
|
|
15
|
+
getNewPage(): Promise<Page>;
|
|
16
|
+
openPage(urlPath: string, options?: {
|
|
17
|
+
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
|
|
18
|
+
}): Promise<Page>;
|
|
19
|
+
waitForSelectorInFrameOrPage(page: Page, selector: string): Promise<Page | FrameLocator>;
|
|
20
|
+
getMyDomain(): string | null;
|
|
21
|
+
getInstanceUrl(): string;
|
|
22
|
+
/**
|
|
23
|
+
* @returns the setup url (e.g. https://[MyDomainName].my.salesforce-setup.com)
|
|
24
|
+
*/
|
|
25
|
+
getLightningSetupUrl(): Promise<string>;
|
|
26
|
+
waitForIdle(page: Page, maxWaitTime?: number): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export declare function throwPageErrors(page: Page): Promise<void>;
|
|
29
|
+
export declare function retry<T>(input: (attemptCount: number) => PromiseLike<T> | T): Promise<T>;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import pRetry from 'p-retry';
|
|
2
|
+
import { chromium, } from 'playwright';
|
|
3
|
+
import { LoginPage } from './pages/login.js';
|
|
4
|
+
const ERROR_DIV_SELECTOR = '#errorTitle';
|
|
5
|
+
const ERROR_DIVS_SELECTOR = 'div.errorMsg';
|
|
6
|
+
const VF_IFRAME_SELECTOR = 'force-aloha-page iframe[name^=vfFrameId]';
|
|
7
|
+
export class Browserforce {
|
|
8
|
+
org;
|
|
9
|
+
logger;
|
|
10
|
+
browser;
|
|
11
|
+
context;
|
|
12
|
+
page;
|
|
13
|
+
lightningSetupUrl;
|
|
14
|
+
constructor(org, logger) {
|
|
15
|
+
this.org = org;
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
}
|
|
18
|
+
async login() {
|
|
19
|
+
this.browser = await chromium.launch({
|
|
20
|
+
channel: process.env.CI ? 'chrome' : undefined,
|
|
21
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
22
|
+
headless: !(process.env.BROWSER_DEBUG === 'true'),
|
|
23
|
+
slowMo: parseInt(process.env.BROWSER_SLOWMO, 10) ?? 0,
|
|
24
|
+
});
|
|
25
|
+
this.context = await this.browser.newContext({
|
|
26
|
+
viewport: { width: 1024, height: 768 },
|
|
27
|
+
});
|
|
28
|
+
// Start tracing if PLAYWRIGHT_TRACE is set
|
|
29
|
+
if (process.env.PLAYWRIGHT_TRACE === 'true') {
|
|
30
|
+
await this.context.tracing.start({
|
|
31
|
+
screenshots: true,
|
|
32
|
+
snapshots: true,
|
|
33
|
+
sources: true,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const page = await this.getNewPage();
|
|
37
|
+
try {
|
|
38
|
+
const loginPage = new LoginPage(page);
|
|
39
|
+
await loginPage.login(this.org);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await page.close();
|
|
43
|
+
}
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
async logout() {
|
|
47
|
+
if (this.browser) {
|
|
48
|
+
// Stop tracing and save if it was started
|
|
49
|
+
if (process.env.PLAYWRIGHT_TRACE === 'true') {
|
|
50
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
51
|
+
const tracePath = `trace-${timestamp}.zip`;
|
|
52
|
+
await this.context.tracing.stop({ path: tracePath });
|
|
53
|
+
if (this.logger) {
|
|
54
|
+
this.logger.log(`Playwright trace saved to: ${tracePath}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await this.browser.close();
|
|
58
|
+
}
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
async throwPageErrors(page) {
|
|
62
|
+
await throwPageErrors(page);
|
|
63
|
+
}
|
|
64
|
+
async getNewPage() {
|
|
65
|
+
const page = await this.context.newPage();
|
|
66
|
+
page.setDefaultNavigationTimeout(parseInt(process.env.BROWSERFORCE_NAVIGATION_TIMEOUT_MS ?? '90000', 10));
|
|
67
|
+
return page;
|
|
68
|
+
}
|
|
69
|
+
// path instead of url
|
|
70
|
+
async openPage(urlPath, options) {
|
|
71
|
+
let page;
|
|
72
|
+
const result = await pRetry(async () => {
|
|
73
|
+
page = await this.getNewPage();
|
|
74
|
+
const setupUrl = urlPath.startsWith('lightning')
|
|
75
|
+
? await this.getLightningSetupUrl()
|
|
76
|
+
: this.getInstanceUrl();
|
|
77
|
+
const url = `${setupUrl}/${urlPath}`;
|
|
78
|
+
const response = await page.goto(url, options ?? { waitUntil: 'load' });
|
|
79
|
+
if (response) {
|
|
80
|
+
if (!response.ok()) {
|
|
81
|
+
await this.throwPageErrors(page);
|
|
82
|
+
throw new Error(`${response.status()}: ${response.statusText()}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return page;
|
|
86
|
+
}, {
|
|
87
|
+
onFailedAttempt: async (context) => {
|
|
88
|
+
if (this.logger) {
|
|
89
|
+
this.logger.warn(`retrying ${context.retriesLeft} more time(s) because of "${context.error}"`);
|
|
90
|
+
}
|
|
91
|
+
if (page) {
|
|
92
|
+
try {
|
|
93
|
+
await page.close();
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
// not handled
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
retries: parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES ?? '4', 10),
|
|
101
|
+
minTimeout: parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS ?? '4000', 10),
|
|
102
|
+
});
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
// If LEX is enabled, the classic url will be opened in an iframe.
|
|
106
|
+
// Wait for either the selector in the page or in the iframe.
|
|
107
|
+
// returns the page or the frame locator
|
|
108
|
+
async waitForSelectorInFrameOrPage(page, selector) {
|
|
109
|
+
await page.locator(`${selector}, ${VF_IFRAME_SELECTOR}`).first().waitFor();
|
|
110
|
+
const iframeCount = await page.locator(VF_IFRAME_SELECTOR).count();
|
|
111
|
+
if (iframeCount > 0) {
|
|
112
|
+
const frameLocator = page.frameLocator(VF_IFRAME_SELECTOR);
|
|
113
|
+
await frameLocator.locator(selector).first().waitFor();
|
|
114
|
+
return frameLocator;
|
|
115
|
+
}
|
|
116
|
+
await page.locator(selector).first().waitFor();
|
|
117
|
+
return page;
|
|
118
|
+
}
|
|
119
|
+
getMyDomain() {
|
|
120
|
+
const instanceUrl = this.getInstanceUrl();
|
|
121
|
+
// acme.my.salesforce.com
|
|
122
|
+
// acme--<sandboxName>.csN.my.salesforce.com
|
|
123
|
+
const matches = instanceUrl.match(/https:\/\/(.*)\.my\.salesforce\.com/);
|
|
124
|
+
if (matches) {
|
|
125
|
+
return matches[1];
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
getInstanceUrl() {
|
|
130
|
+
// sometimes the instanceUrl includes a trailing slash
|
|
131
|
+
return this.org.getConnection().instanceUrl?.replace(/\/$/, '');
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* @returns the setup url (e.g. https://[MyDomainName].my.salesforce-setup.com)
|
|
135
|
+
*/
|
|
136
|
+
async getLightningSetupUrl() {
|
|
137
|
+
if (!this.lightningSetupUrl) {
|
|
138
|
+
const page = await this.getNewPage();
|
|
139
|
+
try {
|
|
140
|
+
const lightningResponse = await page.goto(`${this.getInstanceUrl()}/lightning/setup/SetupOneHome/home`, { waitUntil: 'load' });
|
|
141
|
+
this.lightningSetupUrl = new URL(lightningResponse.url()).origin;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
await page.close();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return this.lightningSetupUrl;
|
|
148
|
+
}
|
|
149
|
+
async waitForIdle(page, maxWaitTime = 2000) {
|
|
150
|
+
try {
|
|
151
|
+
await page.waitForLoadState('networkidle', { timeout: maxWaitTime });
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
console.log(`Waited ${maxWaitTime}ms, continuing regardless of network state`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export async function throwPageErrors(page) {
|
|
159
|
+
const errorLocator = page.locator(ERROR_DIV_SELECTOR);
|
|
160
|
+
const errorCount = await errorLocator.count();
|
|
161
|
+
if (errorCount > 0) {
|
|
162
|
+
const errorMsg = await errorLocator.first().innerText();
|
|
163
|
+
if (errorMsg && errorMsg.trim()) {
|
|
164
|
+
throw new Error(errorMsg.trim());
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const errorDivsLocator = page.locator(ERROR_DIVS_SELECTOR);
|
|
168
|
+
const errorDivsCount = await errorDivsLocator.count();
|
|
169
|
+
if (errorDivsCount > 0) {
|
|
170
|
+
const errorMessages = [];
|
|
171
|
+
for (let i = 0; i < errorDivsCount; i++) {
|
|
172
|
+
const text = await errorDivsLocator.nth(i).innerText();
|
|
173
|
+
errorMessages.push(text);
|
|
174
|
+
}
|
|
175
|
+
const errorMsg = errorMessages
|
|
176
|
+
.map((m) => m.trim())
|
|
177
|
+
.join(' ')
|
|
178
|
+
.trim();
|
|
179
|
+
if (errorMsg) {
|
|
180
|
+
throw new Error(errorMsg);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export async function retry(input) {
|
|
185
|
+
const res = await pRetry(input, {
|
|
186
|
+
onFailedAttempt: (context) => {
|
|
187
|
+
console.warn(`retrying ${context.retriesLeft} more time(s) because of "${context.error}"`);
|
|
188
|
+
},
|
|
189
|
+
retries: parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES ?? '6', 10),
|
|
190
|
+
minTimeout: parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS ?? '4000', 10),
|
|
191
|
+
});
|
|
192
|
+
return res;
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=browserforce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browserforce.js","sourceRoot":"","sources":["../src/browserforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BrowserforceCommand } from '../../browserforce-command.js';
|
|
2
|
+
type BrowserforceApplyResponse = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare class BrowserforceApply extends BrowserforceCommand<BrowserforceApplyResponse> {
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
run(): Promise<BrowserforceApplyResponse>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { BrowserforceCommand } from '../../browserforce-command.js';
|
|
2
|
+
export class BrowserforceApply extends BrowserforceCommand {
|
|
3
|
+
static description = 'apply a plan from a definition file';
|
|
4
|
+
static examples = [
|
|
5
|
+
`$ <%= config.bin %> <%= command.id %> -f ./config/currency.json --target-org myOrg@example.com
|
|
6
|
+
logging in... done
|
|
7
|
+
Applying definition file ./config/currency.json to org myOrg@example.com
|
|
8
|
+
[CompanyInformation] retrieving state... done
|
|
9
|
+
[CompanyInformation] changing 'defaultCurrencyIsoCode' to '"English (South Africa) - ZAR"'... done
|
|
10
|
+
logging out... done
|
|
11
|
+
`,
|
|
12
|
+
];
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags } = await this.parse(BrowserforceApply);
|
|
15
|
+
this.log(`Applying definition file ${flags.definitionfile} to org ${flags['target-org'].getUsername()}`);
|
|
16
|
+
for (const setting of this.settings) {
|
|
17
|
+
const driver = setting.Driver;
|
|
18
|
+
const instance = new driver(this.bf);
|
|
19
|
+
this.spinner.start(`[${driver.name}] retrieving state`);
|
|
20
|
+
let state;
|
|
21
|
+
try {
|
|
22
|
+
state = await instance.retrieve(setting.value);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
this.spinner.stop('failed');
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
this.spinner.stop();
|
|
29
|
+
const diff = instance.diff(state, setting.value);
|
|
30
|
+
if (diff !== undefined) {
|
|
31
|
+
this.spinner.start(`[${driver.name}] ${Object.keys(diff)
|
|
32
|
+
.map((key) => {
|
|
33
|
+
return `changing '${key}' to '${JSON.stringify(diff[key])}'`;
|
|
34
|
+
})
|
|
35
|
+
.join('\n')}`);
|
|
36
|
+
try {
|
|
37
|
+
await instance.apply(diff);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
this.spinner.stop('failed');
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
this.spinner.stop();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.log(`[${driver.name}] no action necessary`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
success: true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/commands/browserforce/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAMpE,MAAM,OAAO,iBAAkB,SAAQ,mBAA8C;IAC5E,MAAM,CAAC,WAAW,GAAG,qCAAqC,CAAC;IAC3D,MAAM,CAAC,QAAQ,GAAG;QACvB;;;;;;GAMD;KACA,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CACN,4BAA4B,KAAK,CAAC,cAAc,WAAW,KAAK,CAC9D,YAAY,CACb,CAAC,WAAW,EAAE,EAAE,CAClB,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,oBAAoB,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC;YACV,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACjD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;qBAClC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;oBACX,OAAO,aAAa,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;gBAC/D,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;gBACF,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC5B,MAAM,GAAG,CAAC;gBACZ,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,uBAAuB,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,OAAO;YACL,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BrowserforceCommand } from '../../browserforce-command.js';
|
|
2
|
+
type BrowserforceApplyResponse = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare class BrowserforcePlanCommand extends BrowserforceCommand<BrowserforceApplyResponse> {
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
run(): Promise<BrowserforceApplyResponse>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { writeFile } from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { BrowserforceCommand } from '../../browserforce-command.js';
|
|
4
|
+
export class BrowserforcePlanCommand extends BrowserforceCommand {
|
|
5
|
+
static description = 'retrieve state and generate plan file';
|
|
6
|
+
static examples = [
|
|
7
|
+
`$ <%= config.bin %> <%= command.id %> -f ./config/currency.json --target-org myOrg@example.com
|
|
8
|
+
logging in... done
|
|
9
|
+
Generating plan with definition file ./config/currency.json from org myOrg@example.com
|
|
10
|
+
[CompanyInformation] retrieving state... done
|
|
11
|
+
[CompanyInformation] generating plan... done
|
|
12
|
+
logging out... done
|
|
13
|
+
`,
|
|
14
|
+
];
|
|
15
|
+
async run() {
|
|
16
|
+
const { flags } = await this.parse(BrowserforcePlanCommand);
|
|
17
|
+
this.log(`Generating plan with definition file ${flags.definitionfile} from org ${flags['target-org'].getUsername()}`);
|
|
18
|
+
const state = {
|
|
19
|
+
settings: {},
|
|
20
|
+
};
|
|
21
|
+
const plan = {
|
|
22
|
+
settings: {},
|
|
23
|
+
};
|
|
24
|
+
for (const setting of this.settings) {
|
|
25
|
+
const driver = setting.Driver;
|
|
26
|
+
const instance = new driver(this.bf);
|
|
27
|
+
this.spinner.start(`[${driver.name}] retrieving state`);
|
|
28
|
+
let driverState;
|
|
29
|
+
try {
|
|
30
|
+
driverState = await instance.retrieve(setting.value);
|
|
31
|
+
state.settings[setting.key] = driverState;
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
this.spinner.stop('failed');
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
this.spinner.stop();
|
|
38
|
+
this.spinner.start(`[${driver.name}] generating plan`);
|
|
39
|
+
const driverPlan = instance.diff(driverState, setting.value);
|
|
40
|
+
plan.settings[setting.key] = driverPlan;
|
|
41
|
+
this.spinner.stop();
|
|
42
|
+
}
|
|
43
|
+
if (flags.statefile) {
|
|
44
|
+
this.spinner.start('writing state file');
|
|
45
|
+
await writeFile(path.resolve(flags.statefile), JSON.stringify(state, null, 2));
|
|
46
|
+
this.spinner.stop();
|
|
47
|
+
}
|
|
48
|
+
if (flags.planfile) {
|
|
49
|
+
this.spinner.start('writing plan file');
|
|
50
|
+
await writeFile(path.resolve(flags.planfile), JSON.stringify(plan, null, 2));
|
|
51
|
+
this.spinner.stop();
|
|
52
|
+
}
|
|
53
|
+
return { success: true };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/commands/browserforce/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAMpE,MAAM,OAAO,uBAAwB,SAAQ,mBAA8C;IAClF,MAAM,CAAC,WAAW,GAAG,uCAAuC,CAAC;IAC7D,MAAM,CAAC,QAAQ,GAAG;QACvB;;;;;;GAMD;KACA,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC5D,IAAI,CAAC,GAAG,CACN,wCACE,KAAK,CAAC,cACR,aAAa,KAAK,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,EAAE,CACjD,CAAC;QACF,MAAM,KAAK,GAAG;YACZ,QAAQ,EAAE,EAAE;SACb,CAAC;QACF,MAAM,IAAI,GAAG;YACX,QAAQ,EAAE,EAAE;SACb,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,oBAAoB,CAAC,CAAC;YACxD,IAAI,WAAW,CAAC;YAChB,IAAI,CAAC;gBACH,WAAW,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACrD,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;YAC5C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,mBAAmB,CAAC,CAAC;YACvD,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACzC,MAAM,SAAS,CACb,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAC7B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAC/B,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACxC,MAAM,SAAS,CACb,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC5B,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAC9B,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BrowserforcePlugin } from './plugin.js';
|
|
2
|
+
type Drivers = {
|
|
3
|
+
[key: string]: typeof BrowserforcePlugin;
|
|
4
|
+
};
|
|
5
|
+
type Data = {
|
|
6
|
+
settings?: unknown;
|
|
7
|
+
};
|
|
8
|
+
type Config = {
|
|
9
|
+
Driver: typeof BrowserforcePlugin;
|
|
10
|
+
key: string;
|
|
11
|
+
value: unknown;
|
|
12
|
+
};
|
|
13
|
+
export declare class ConfigParser {
|
|
14
|
+
static parse(drivers: Drivers, data: Data): Config[];
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class ConfigParser {
|
|
2
|
+
static parse(drivers, data) {
|
|
3
|
+
const settings = [];
|
|
4
|
+
if (data?.settings) {
|
|
5
|
+
for (const driverName of Object.keys(data.settings)) {
|
|
6
|
+
if (drivers[driverName]) {
|
|
7
|
+
settings.push({
|
|
8
|
+
Driver: drivers[driverName],
|
|
9
|
+
key: driverName,
|
|
10
|
+
value: data.settings[driverName],
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
throw new Error(`Could not find plugin named '${driverName}' in definition: ${JSON.stringify(data)}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
throw new Error(`Missing 'settings' attribute in definition: ${JSON.stringify(data)}`);
|
|
20
|
+
}
|
|
21
|
+
return settings;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=config-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"AAgBA,MAAM,OAAO,YAAY;IAChB,MAAM,CAAC,KAAK,CAAC,OAAgB,EAAE,IAAU;QAC9C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC;YACnB,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpD,IAAI,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxB,QAAQ,CAAC,IAAI,CAAC;wBACZ,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC;wBAC3B,GAAG,EAAE,UAAU;wBACf,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;qBACjC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CACb,gCAAgC,UAAU,oBAAoB,IAAI,CAAC,SAAS,CAC1E,IAAI,CACL,EAAE,CACJ,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,+CAA+C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/index.js
ADDED
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workaround as the Metadata API (converted from XML) returns an object instead of an array of length 1
|
|
3
|
+
* @param prop result of a Metadata API call (array or object)
|
|
4
|
+
*/
|
|
5
|
+
export function ensureArray(prop) {
|
|
6
|
+
if (Array.isArray(prop)) {
|
|
7
|
+
return prop;
|
|
8
|
+
}
|
|
9
|
+
if (prop === undefined || prop === null) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
return [prop];
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=jsforce-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsforce-utils.js","sourceRoot":"","sources":["../src/jsforce-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAI,IAAa;IAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|