MacOS 15.4 broken sheets navigate to path
Title
MacOS 15.4 broken sheets navigate to path
What do you expect to happen when you run the script/macro?
Loads I/O settings
Are you seeing an error?
Element was not found - line 39
Script fails to open the 'go' sheet using sf.keyboard.type({ text:'/')}
What happens when you run this script?
Script fails to open the 'go' sheet using sf.keyboard.type({ text:'/')}
How were you running this script?
I clicked the "Run Script" or "Run Macro" button in SoundFlow
How important is this issue to you?
5
Details
{ "inputExpected": "Loads I/O settings", "inputIsError": true, "inputError": "Element was not found - line 39 \n\nScript fails to open the 'go' sheet using sf.keyboard.type({ text:'/')}", "inputWhatHappens": "Script fails to open the 'go' sheet using sf.keyboard.type({ text:'/')}", "inputHowRun": { "key": "-MpfwYA4I6GGlXgvp5j1", "title": "I clicked the \"Run Script\" or \"Run Macro\" button in SoundFlow" }, "inputImportance": 5, "inputTitle": "MacOS 15.4 broken sheets navigate to path" }
Source
const ioSettingsFolder = "~/Documents/Pro Tools/IO Settings/";
function importBusSettings(presetName) {
//Activate Pro Tools Window
sf.ui.proTools.appActivateMainWindow();
//Open I/O Window
sf.ui.proTools.menuClick({
menuPath: ["Setup", "I/O..."],
});
const ioWin = sf.ui.proTools.windows.whoseTitle.is('I/O Setup').first;
//Select "Bus" Tab
ioWin.radioButtons.whoseTitle.startsWith('Bus').first.elementClick();
//Wait for Tab ("Active Busses" text is unique to the bus tab)
ioWin.children.whoseRole.is("AXStaticText").whoseValue.is('Active Busses:').first.elementWaitFor();
//Click 'Import Settings...'
ioWin.buttons.whoseTitle.is('Import Settings...').first.elementClick();
const openWin = sf.ui.proTools.windows.whoseTitle.is('Open').first;
//const openWinLocation = sf.ui.proTools.windows.whoseTitle.is("Open").first.popupButtons.whoseTitle.is("Where:").first
//Wait for 'Open' window
openWin.elementWaitFor()
//openWinLocation.elementWaitFor()
//Wait Again
//sf.wait({intervalMs: 200})
//Open 'go' sheet
sf.keyboard.type({ text: '/' });
//Wait for Open window
openWin.sheets.first.elementWaitFor();
const sheet = openWin.sheets.first;
if (sheet.comboBoxes.first.exists) {
//Set preset name
sheet.comboBoxes.first.value.value = presetName;
//Click "Go"
sheet.buttons.whoseTitle.is('Go').first.elementClick();
} else {
//Set presetPath
sheet.textFields.first.value.value = `${ioSettingsFolder}${presetName}`;
sf.keyboard.press({ keys: 'return' });
}
sheet.elementWaitFor({ waitType: "Disappear" });
const openBtn = openWin.buttons.whoseTitle.is("Open").first;
let tryCount = 0;
while (!openBtn.isEnabled || tryCount >= 10) {
sf.wait({ intervalMs: 20 });
tryCount++
}
//Click Open
openWin.buttons.whoseTitle.is("Open").first.elementClick();
//Wait for Dialog window
sf.ui.proTools.confirmationDialog.elementWaitFor();
//Delete unused buses prompt
sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('No').first.elementClick();
//Click OK
ioWin.buttons.whoseTitle.is('OK').first.elementClick();
}
importBusSettings("Keys Gates.pio");
Links
User UID: sKu19XXNXHYSdEMmZtHz8CozbdS2
Feedback Key: sffeedback:sKu19XXNXHYSdEMmZtHz8CozbdS2:-ONSTon7HvPpspVFkmNK
Feedback ZIP: 9cI0LArKCpC9VBHSfENZMOoxoD11g9yh+I5KuAkuZGiB5fn2/t+8U2lQl2GPfmBJ7eLx+U3uVSgO1BPRyoKNf/dWdyadRr8qfwPYP3S4F3oVvn/CsuALjwBQ52LlZxcsQpVvY6vRzt8alwFe665XGYPeOG67K2u9PSz1sxfnHl+rjkb5cKdBIsIZd/fBL3xnnNaUZRCmDYRdwffnw3Ih5jh9RItLNc4I5KBeAok8URni9zlS/3gQqNDH00PYDW8bZA3McMegMizg9imPDS/eqsNSYCCKZL8Vkf2SrSYmD4tk2XGdQK9OLoKjaRxLHPSvMXprAym8tXJsAXR3mH8IzZVeUAuBCXbEn+SXY4GLOJ0=
Linked from:
- FForrester Savell @Forrester_Savell
This is easily fixed with
sf.wait({intervalMs: 200})
before calling the 'go' window.However, I'm intrigued as to what element is not focused and needs to be waited for before 'slash' is pressed to open 'Go' window. I thought it might be the
.popupButtons.whoseTitle.is("Where:")
but that's not it.Kitch Membery @Kitch2025-04-10 17:50:29.048Z
In this case, I believe the failure is occurring because the script has to wait for the OS to complete the animation of the dialog opening. Therefore, a manual wait might be necessary here.
- FForrester Savell @Forrester_Savell
Hey @Kitch
I'm seeing some variation in the wait time necessary for the Go sheet to work across different scripts/sessions. Is this something that would likely be addressed in a Soundflow update relevant to changes in MacOS15.4, so that the
openWin.elementWaitFor()
specifically waits for the animation to complete before moving on?Kitch Membery @Kitch2025-04-14 17:10:02.540Z
Thanks @Forrester_Savell,
When I have a moment, I'll have to dig deeper to see if there's a way to identify when the Go sheet appears.
- SIn reply toForrester_Savell⬆:SoundFlow Bot @soundflowbot
This issue is now tracked internally by SoundFlow as SF-1699
- FIn reply toForrester_Savell⬆:Forrester Savell @Forrester_Savell
Hey @Kitch have you had any luck with this?
I'm still getting issues trying to handle the process of navigating to a folder, specifically waiting for the "Go" sheet, that works across a range of sessions.
Using a
sf.wait({intervalMS:1000})
works 90% of the time, but with the odd session that is large and slow, it will fail due to the arbitrary wait.I've tried all manner of callbacks and waitFor's but nothing seems to work.
// Open "Go to" sheet sf.waitFor({ callback: () => { sf.keyboard.press({ keys: 'slash' }); return openWin.sheets.first.exists; }, pollingInterval: 100, timeout: 2000 });
@raphaelsepulveda , when I use your callback method, I find it enters an unwanted '/' in the textfield about 50% time, I presume due to some sort of lag in the callback process. Have you experienced that?
Raphael Sepulveda @raphaelsepulveda2025-08-04 17:12:20.692Z
@Forrester_Savell, ah yes. I didn't notice this in the context of the full script where this is taken from, since it immediately replaces the text with the desired file path.
It just needs a slight tweak to avoid that extra slash:
// Open "Go to" sheet sf.waitFor({ callback: () => { if (openWin.sheets.first.exists) return true; sf.keyboard.press({ keys: 'slash' }); }, pollingInterval: 100, timeout: 2000 });
- FForrester Savell @Forrester_Savell
Thanks as always @raphaelsepulveda !
I have another learning question. I was stumbling on waiting for an overwrite confirmation dialog during file exporting. Initially I was using
sf.waitFor({ timeout: 2000, pollingInterval: 100, callback: () => { sf.ui.proTools.confirmationButtonDialog.buttons.whoseTitle.is("Yes").first.exists; // I also tried checking for the window //sf.ui.proTools.confirmationButtonDialog.children.whoseRole.is("AXStaticText").whoseValue.contains("already exists. Do you want to replace it?").first; }, });
However the above code doesn't work.
It wasn't until I added the if statement. and return, like your example above, that it worked.
sf.waitFor({ callback: () => { if (sf.ui.proTools.confirmationButtonDialog.buttons.whoseTitle.is("Yes").first) return true; }, pollingInterval: 100, timeout: 2000 });
So I'm confused as to why the first example doesn't work, when I can see many uses of callbacks that don't use the if/return. eg. I/O Setup New Path name field interaction broken with PT2024.10 #post-11
Is it the nature of the element its checking or?
Raphael Sepulveda @raphaelsepulveda2025-08-05 05:22:57.617Z
@Forrester_Savell, it's due to the different ways a value can be returned in an arrow function.
In your first example, since you're using brackets in the arrow function, then you need to add
return
in order to return a value, like so:sf.waitFor({ timeout: 2000, pollingInterval: 100, callback: () => { return sf.ui.proTools.confirmationButtonDialog.buttons.whoseTitle.is("Yes").first.exists; }, });
If the brackets are omitted then
return
is not necessary as anything you put after the arrow will be returned. This is what is happening in the callback examples you've seen:sf.waitFor({ timeout: 2000, pollingInterval: 100, callback: () => sf.ui.proTools.confirmationButtonDialog.buttons.whoseTitle.is("Yes").first.exists, });
Hope that clears up things a bit!