Hello
I've a simple script that clears the Undo History queue. If I comment out lines 13-25, the script works fine, but if I check to see if the "Clear Undo Queue" menuitem is enabled, the script fails with 'Popup menu was not found'. I've confirmed it is enabled and there are Undo steps in the queue.
Specifically, if I have the line const undoHistoryMenu = undoHistoryBtn.popupMenuFetchAllItems().menuItems, it breaks. How does fetching the popupmenu cause the popupMenuSelect to fail?
What am I doing wrong here?
sf.ui.proTools.appActivateMainWindow();
log('Attempting to clear Undo History...');
// Open the Undo History window
sf.ui.proTools.menuClick({ menuPath: ["Window", "Undo History"], targetValue: "Enable" });
// Define the Undo History button that opens the menu
const undoHistoryBtn = sf.ui.proTools.windows.whoseTitle.is("Undo History").first
.children.whoseRole.is("AXMenuButton").whoseTitle.is("Undo Actions").first;
// This below section of code works correctly if the "Clear Undo Queue" button is greyed out, but fails if it's not
/* // Fetch all enabled menu items for the undo history button
let undoHistoryMenu = undoHistoryBtn.popupMenuFetchAllItems().menuItems
.filter(mi => mi.element.isEnabled)
.map(mi => mi.path.join(" > "));
log(undoHistoryMenu)
// Check if "Clear Undo Queue" exists in the enabled menu items
if (!undoHistoryMenu.includes("Clear Undo Queue")) {
log("No Undo History to delete.");
throw 0; // Exit if no Undo History items are available to delete
} */
// Otherwise, clear the undo queue
undoHistoryBtn.popupMenuSelect({
menuPath: ["Clear Undo Queue"],
});
// Confirm the action if a confirmation dialog appears
if (sf.ui.proTools.confirmationDialog.exists) {
const yesButton = sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is("Yes").first;
if (yesButton.exists) {
yesButton.elementClick();
sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear" });
}
}
log('Undo History cleared.');
// Close the Undo History window
sf.ui.proTools.menuClick({ menuPath: ["Window", "Undo History"], targetValue: "Disable" });
Chris Shaw @Chris_Shaw2024-10-28 21:02:05.423ZGive this a try:
sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); log('Attempting to clear Undo History...'); // Open the Undo History window sf.ui.proTools.menuClick({ menuPath: ["Window", "Undo History"], targetValue: "Enable" }); // Define the Undo History button that opens the menu const undoHistoryWin = sf.ui.proTools.windows.whoseTitle.is("Undo History").first; undoHistoryWin.elementWaitFor(); const undoHistoryPopupBtn = undoHistoryWin.children.whoseRole.is("AXMenuButton").whoseTitle.is("Undo Actions").first; const isClearEnabled = undoHistoryPopupBtn.popupMenuSelect({ menuSelector: items => items.find(mi => mi.path[0] === "Clear Undo Queue" && mi.element.exists && mi.element.isEnabled) }, () => log("No Undo History to Clear")).success; if (isClearEnabled) { const yesBtn = sf.ui.proTools.focusedWindow.buttons.whoseTitle.is("Yes").first; sf.waitFor({ callback: () => { sf.wait({intervalMs:150}) sf.ui.proTools.windows.invalidate() return yesBtn.exists } }) yesBtn.elementClick(); log("Undo History Cleared") } // Close the Undo History window sf.ui.proTools.menuClick({ menuPath: ["Window", "Undo History"], targetValue: "Disable" });
Chris Shaw @Chris_Shaw2024-10-28 21:05:52.998ZLine 16 does a few things:
It looks for a "Clear Undo Queue" menu item that exists and is enabled and attempts to click it.
If it doesn't exist it logs "No Undo History to Clear" and sets `isClearEnabled" to false.The rest should be self explanatory
- In reply toChris_Shaw⬆:
Chris Shaw @Chris_Shaw2024-10-28 21:28:45.596ZYou might have been getting an error because the script wasn't waiting for the Undo History window to open before fetching the popup menu items.
- FForrester Savell @Forrester_Savell
Thanks Chris.
Your script works great. I'm still a bit baffled by the error on mine. Even if the window is already visible, or if I add
const undoHistoryWin = sf.ui.proTools.windows.whoseTitle.is("Undo History").first; undoHistoryWin.elementWaitFor();it still gives the popupmenu error if it creates the
undoHistoryMenu = undoHistoryBtn.popupMenuFetchAllItems().menuItemsvariable.Also I have a followup question - I pulled the
popupMenuFetchAllItems().menuItems.filter(mi => mi.element.isEnabled)from another forum post (Exclude Greyed out options from a pop up menu in popup search #post-2) relating to identifying greyed-out menu items. Where is theisEnabledgetting its information from? If I log theundoHistoryMenu, none of the information changes whether the menu items are greyed out or not.
Chris Shaw @Chris_Shaw2024-10-28 23:03:11.062ZI think the issue may be here (line 14):
let undoHistoryMenu = undoHistoryBtn.popupMenuFetchAllItems().menuItems .filter(mi => mi.element.isEnabled) .map(mi => mi.path.join(" > "));If you put a
throw 0after this at line 17 the popup menu stays open. I'm thinking that when SF tries to click the clear the Undo Queue (line 27) it cannot find the popup button because the menu is still open.
Try adding adismissMenu: trueat line 14 like this:let undoHistoryMenu = undoHistoryBtn.popupMenuFetchAllItems({dismissMenu:true}).menuItems .filter(mi => mi.element.isEnabled) .map(mi => mi.path.join(" > "));
Chris Shaw @Chris_Shaw2024-10-28 23:05:55.255ZOn my system (2024.6 / Ventura/ SF 5.9 - you can manually download this now) I don't have any issue other than the script doesn't click the "Yes" button in the confirmation window. That's why I wrote an alternate routine to detect it.
Without seeing your script in action and failing I can't be 100% sure of where the fault is happening other than what I described above.
Chris Shaw @Chris_Shaw2024-10-28 23:13:30.901ZOut of curiosity, what MacOS/PT/SF versions are you running?
- FForrester Savell @Forrester_Savell
I'm running SF 5.9.0, macOS 13.6.3 and yesterday I was running PT2024.6 and have tried 2024.10 this morning. Same results.
- In reply toChris_Shaw⬆:FForrester Savell @Forrester_Savell
That makes sense, but its not solving it. If I use
let undoHistoryMenu = undoHistoryBtn.popupMenuFetchAllItems({ dismissMenu: true }).menuItems .filter(mi => mi.element.isEnabled) .map(mi => mi.path.join(" > ")); log(undoHistoryMenu)it causes the
undoHistoryMenuarray to be empty. Perhaps its something to do withpopupMenuFetchAllItemsvspopupMenuSelect?I think it will remain a mystery, as your code works well. Thanks for you help Chris.