Skip to content

Commit

Permalink
Merge pull request #372 from amtrack/feat/deactivate-picklist-values
Browse files Browse the repository at this point in the history
feat: (de)activate picklist values
  • Loading branch information
amtrack authored Jan 11, 2021
2 parents 65bf462 + 63def01 commit 8855c86
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 13 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ Here is a full blown example showing most of the supported settings in action:
"value": "CD",
"newValue": "Media",
"absent": true
},
{
"metadataType": "CustomField",
"metadataFullName": "Vehicle__c.Features__c",
"value": "CD",
"newValue": "AC",
"active": false
}
]
},
Expand Down
15 changes: 15 additions & 0 deletions src/plugins/picklists/activate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "../schema.json",
"settings": {
"picklists": {
"picklistValues": [
{
"metadataType": "CustomField",
"metadataFullName": "Vehicle__c.Features__c",
"value": "AC",
"active": true
}
]
}
}
}
15 changes: 15 additions & 0 deletions src/plugins/picklists/deactivate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "../schema.json",
"settings": {
"picklists": {
"picklistValues": [
{
"metadataType": "CustomField",
"metadataFullName": "Vehicle__c.Features__c",
"value": "AC",
"active": false
}
]
}
}
}
36 changes: 36 additions & 0 deletions src/plugins/picklists/index.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,40 @@ describe(Picklists.name, function() {
replaceCmd.output.toString()
);
});
it('should deactivate picklist value', () => {
const cmd = child.spawnSync(path.resolve('bin', 'run'), [
'browserforce:apply',
'-f',
path.resolve(path.join(__dirname, 'deactivate.json'))
]);
assert.deepStrictEqual(cmd.status, 0, cmd.output.toString());
assert(
/changing 'picklistValues' to.*/.test(cmd.output.toString()),
cmd.output.toString()
);
});
it('should activate picklist value', () => {
const cmd = child.spawnSync(path.resolve('bin', 'run'), [
'browserforce:apply',
'-f',
path.resolve(path.join(__dirname, 'activate.json'))
]);
assert.deepStrictEqual(cmd.status, 0, cmd.output.toString());
assert(
/changing 'picklistValues' to.*/.test(cmd.output.toString()),
cmd.output.toString()
);
});
it('should not do anything when the picklist values do not exist', () => {
const cmd = child.spawnSync(path.resolve('bin', 'run'), [
'browserforce:apply',
'-f',
path.resolve(path.join(__dirname, 'activate.json'))
]);
assert.deepStrictEqual(cmd.status, 0, cmd.output.toString());
assert(
/no action necessary/.test(cmd.output.toString()),
cmd.output.toString()
);
});
});
19 changes: 15 additions & 4 deletions src/plugins/picklists/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ export default class Picklists extends BrowserforcePlugin {
);
const page = await this.browserforce.openPage(picklistUrl);
const picklistPage = new PicklistPage(page);
if (action.absent) {
if (action.active !== undefined) {
await picklistPage.clickActivateDeactivateActionForValue(
action.value,
action.active
);
} else if (action.absent) {
const replacePage = await picklistPage.clickDeleteActionForValue(
action.value
);
Expand Down Expand Up @@ -104,10 +109,16 @@ function isActionRequired(action, values) {
const valueGiven = action.value !== undefined && action.value !== null;
const newValueGiven =
action.newValue !== undefined && action.newValue !== null;
if (valueGiven && !values.includes(action.value)) {
return false;
if (valueGiven) {
const match = values.find(x => x.value === action.value);
if (!match) {
return false;
}
if (action.active !== undefined && action.active === match.active) {
return false;
}
}
if (newValueGiven && !values.includes(action.newValue)) {
if (newValueGiven && !values.find(x => x.value === action.newValue)) {
return false;
}
return true;
Expand Down
69 changes: 60 additions & 9 deletions src/plugins/picklists/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,45 @@ import { JSHandle } from 'puppeteer';
// - label column is a th (which is not used)
// - xpath indices are 1 based

type PicklistValue = {
value: string;
active: boolean;
};

export class PicklistPage {
private page;

constructor(page) {
this.page = page;
}

public async getPicklistValues(): Promise<Array<string>> {
const xpath = `//tr[td[1]//a[contains(@href, "/setup/ui/picklist_masteredit") or contains(@href, "/setup/ui/picklist_masterdelete")]]//td[2]`;
await this.page.waitForXPath(xpath);
const fullNameHandles = await this.page.$x(xpath);
const innerTextJsHandles = await Promise.all<JSHandle>(
fullNameHandles.map(handle => handle.getProperty('innerText'))
public async getPicklistValues(): Promise<Array<PicklistValue>> {
// wait for New button in any related list
await this.page.waitForSelector('body table input[name="new"]');
const resolvePicklistValueNames = async xpath => {
const fullNameHandles = await this.page.$x(xpath);
const innerTextJsHandles = await Promise.all<JSHandle>(
fullNameHandles.map(handle => handle.getProperty('innerText'))
);
const fullNames = await Promise.all<any>(
innerTextJsHandles.map(handle => handle.jsonValue())
);
return fullNames;
};
const active = await resolvePicklistValueNames(
`//tr[td[1]//a[contains(@href, "/setup/ui/picklist_masteredit")]]//td[2]`
);
const fullNames = await Promise.all<any>(
innerTextJsHandles.map(handle => handle.jsonValue())
const inactive = await resolvePicklistValueNames(
`//tr[td[1]//a[contains(@href, "/setup/ui/picklist_masteractivate")]]//td[2]`
);
return fullNames;
return [
...active.map(x => {
return { value: x, active: true };
}),
...inactive.map(x => {
return { value: x, active: false };
})
];
}

public async clickReplaceActionButton(): Promise<any> {
Expand Down Expand Up @@ -57,6 +78,36 @@ export class PicklistPage {
]);
return new PicklistReplaceAndDeletePage(this.page);
}

public async clickActivateDeactivateActionForValue(
picklistValueApiName: string,
active: boolean
): Promise<any> {
let xpath;
let actionName;
if (active) {
xpath = `//tr[td[2][text() = "${picklistValueApiName}"]]//td[1]//a[contains(@href, "/setup/ui/picklist_masteractivate.jsp")]`;
actionName = 'activate';
} else {
xpath = `//tr[td[2][text() = "${picklistValueApiName}"]]//td[1]//a[contains(@href, "/setup/ui/picklist_masterdelete.jsp") and contains(@href, "deleteType=1")]`;
actionName = 'deactivate';
}
await this.page.waitForXPath(xpath);
const actionLinkHandles = await this.page.$x(xpath);
if (actionLinkHandles.length !== 1) {
throw new Error(
`Could not find ${actionName} action for picklist value: ${picklistValueApiName}`
);
}
this.page.on('dialog', async dialog => {
await dialog.accept();
});
await Promise.all([
this.page.waitForNavigation(),
actionLinkHandles[0].click()
]);
return this.page;
}
}

export class PicklistReplacePage {
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/picklists/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
"type": "boolean",
"description": "replace all blank values (mutually exclusive to replacing an old value)"
},
"active": {
"type": "boolean",
"description": "ensure the picklist value is active/inactive"
},
"absent": {
"type": "boolean",
"description": "ensure the picklist value is absent/deleted"
Expand Down

0 comments on commit 8855c86

Please sign in to comment.