I've been reading some posts here about how to click a single link.
My case is that I have a query that will return multiple elements, and for each of those I'd like to do the following:
Find URL to thumbnail image in children of sibling element.
Copy URL, remove part of it.
Open URL in new browser tab.
Save returned image (now the original). CMD-S keystroke + Return.
Close tab. CMD-W keystroke
Process next XPath element.
My question is, is it possible to, say, execute a first query to get all the "anchor" elements list out first and place the result in a KM variable, and then for each of those, execute a single XPath to read out the sibling URL data and process it?
I'm asking to figure out where to place responsibilities, purely in a huge chunk of JavaScript or can I place some of the logic at KM level, and loop there?
It's very difficult to answer these sorts of questions without having a concrete example to work with and test...
That said – on first inspection I think it likely that you can scrape your main and child URLs with JavaScript and then offload the other tasks to Keyboard Maestro.
Post #3 – Post #6 were accidentally dumped into a private message. Unfortunately the Discourse software wouldn't allow me to move them verbatim, so I had to do it the hard way.
christerdk's messages are labelled as From: @christerdk
Yep, I’ve been experimenting with with some node traversing. There’s are some details that’ll make it a challenge, some items are images and some are video, and there may be a collection the needs to be “swiped”. I can do all that in JavaScript, so I guess I can return a string with a separator character, and then loop that in KM?
Not so sure about the latter, not yet at least, because I don’t believe I saw a split function in the article, that’ll handle an unknown list size?
I’ll follow up and post my findings, so that others can benefit from hearing about the strategy and division of work.
So far so good, I have everything I need in one string now.
I've been looking around in the documentation, and I'm not picking up a tactic loading, splitting and iterating over a string with content "Value1;Value2;Value3".
Following up, I have it running now. But I'm experiencing some behavior, I can't quite get my head around.
I am downloading a list of jpgs and mp4 in Chrome tabs, one at a time. In a previous, more naive version of my script, I waited 5 seconds and 20 seconds respectively to wait for the Save as dialog to show up after a command-s keystroke. Not optimal, and the dialog has a tendency to take it's time to show up with the videos. It worked, until there were some failed saves on the videos.
So after researching a little I replaced the wait time action with if statement that waits for a Save button to be enabled.
Some observations: The Save as dialog shows up (after quite a while), but then it seems as if KM just quickly jumps to the next item in the outer loop, opens up a new tab, not finishing the work in the save as dialog. It reminds me of threaded behavior, from where the if-based wait behavior is activated and onwards. A debugger Start statement inside the if wait is also ignored.
As I was writing out comments in the macro, I realized that I should have made a simple Display text in else-section of the if group with button condition. Turns out that there's no hit on the condition. So no relation "threaded behavior" as far as I see - plesae write it off as a bit of late night tunnel vision.
Now, it's still unclear to me why the condition isn't met. Here's a screen shot of the save dialog, just to rule out any OS differences:
Wrong action, I think. The "If..." action is immediate, the "Save" button doesn't exist (dialog not present yet), so "If..." goes straight to the "otherwise" section.
I'm guessing that what you actually want is a "Pause Until..." action, conditional on "the 'Save' button exists". That hold your macro until the "Save" dialog is present, and then the following actions will set to work on the dialog.
For the sake of anyone trying to do something similar in the future, I decided to make this write up, so the solution is easily accessible without having to scroll through the whole discussion.
The division of work is as follows:
Create a JavaScript function to traverse all nodes and pick up the URLs I needed (jpgs and mp4 links). The result is a linefeed separated list. Currently I'm running this manually to separate the two tasks and overlook the function, but it possible to merge that into the KM macro later. I used QuerySelector to get all the elements needed, but to gather the specifics I had to test for the presence of child elements and so on. I developed the script "raw" in the console of Chrome (no IDE on this Mac). There might be smarter way
The responsibility of the KM macro is to iterate over the collected links, each of these opening a chrome tab, waiting to download, press command-s, wait for dialog with save button to be present and save.
For those new to KM, I recommend a divide and conquer approach:
Meaning not everything needs necessarily to be automated in one, first go. From a generic perspective the solution is essentially two parts, gathering the data in JavaScript and then processing in KM macro. They both have their sets of challenges, so I recommend figuring out the data contract first (in this case the handover of a list of URLs, but can be whatever necessary) and work from there in each part.
By using linefeeds as a separator, one avoids the need for splitting the string by an arbitrary separator in KM. YMMV, it depends on how complex your data is).
A big thank you goes out to @ccstone and @Nige_S for their help!