Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

macos - Missing Value Errors when heavily using Javascript in Safari by Applescript

Sorry for the possibly confusing title.

My problem is that I'd like to download Apple's Command Line Tools for XCode without the need to click on the single buttons. I want to use this for a faster setup of new developer workstations combined with Chef.

The script and error are as follows:

tell application "Safari"
    make new document at end of every document --> document "Ohne Titel"
    set URL of document 1 to "https://developer.apple.com/downloads/index.action"
    get name of document 1 --> "Ohne Titel"
    do JavaScript "var head= document.getElementsByTagName('head')[0];
                   var script= document.createElement('script');
                   script.type= 'text/javascript';
                   script.src= 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
                   head.appendChild(script);" in document 1 --> missing value
    do JavaScript "alert('test')" in document 1 --> missing value
    do JavaScript "document.forms['appleConnectForm']['accountname'].value = 'somename'" in document 1 --> missing value
    do JavaScript "document.forms['appleConnectForm']['accountpassword'].value = 'somepassword'" in document 1 --> missing value
    do JavaScript "document.appleConnectForm.submit();" in document 1 --> missing value
    do JavaScript "var atags = document.getElementsByTagName('a')" in document 1 --> missing value
    do JavaScript "for (var i=0; i<atags.length; i++){ if (atags.textContent=='Command Line Tools for Xcode'){ atags[i].click(); } }" in document 1 --> missing value
    set name of window 1 to "Ohne Titel"
end tell

Updates to the the script and errors I am running into here: https://gist.github.com/1993352

The Javascript on line 17 is properly executed and I see an alert message. Any of the other lines is not executed as expected.

How can I get this to work and is the current Javascript not executed except for this one line?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @Jordan stated above, the missing value returned from do JavaScript does not indicate an error. However, your code suffers from a few problems that do stop it from working:

  1. it does not wait for the page to load completely before trying to access the form – hence your value assignments and submit() call go into the void. You can go fancy and try to wait for a matching window name, but a simple delay will do;
  2. it tries to inspect the text content of all found elements (atags.textContent) instead of the currently looped-over one (atags[i].textContent);
  3. it tries to trigger a click event by calling the click() method, which most browsers refuse to do, ostensibly for security reasons (see this question and answer of mine). As Apple does not include jQuery, the issue is not quite as straightforward to sidestep as in the answer I linked to – you can, however, simulate the click event with a bit of code courtesy of Protolicious’ event.simulate.js.

The following code will do what you asked for:

tell application "Safari"
    set loadDelay to 2 -- in seconds; test for your system
    make new document at end of every document
    set URL of document 1 to "https://developer.apple.com/downloads/index.action"
    delay loadDelay
    do JavaScript "_connectForm = document.forms.appleConnectForm;
                   _connectForm.accountname.value = 'your_accountname';
                   _connectForm.accountpassword.value = 'your_accountpassword';
                   _connectForm.submit();" in document 1
    delay loadDelay
    do JavaScript "var _atags = document.querySelectorAll('a');
                   for (var i=0; i<_atags.length; i++){ 
                       if (_atags[i].innerText.indexOf('Command Line Tools for Xcode') === 0){ 
                           _event = document.createEvent('MouseEvents');
                           _event.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, _atags[i]);
                           _atags[i].dispatchEvent(_event);
                           break;
                       }
                   }" in document 1
end tell

Tested with my own account; download of most recent Xcode Command Line Tools package (to be precise – topmost listed) started successfully.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...