16

I am working on a little project where PhamtomJS will log into my site and upload a plugin to it. I almost have it, except for one strange problem. Although the file.upload portion of my code works perfectly, the Install now button remains disabled. Here is a picture rendered from Phantom:

Screenshot

As you can see, the button is still disabled. So when I try to click it using the getElementById() method, it will not work. Nor will it work if I try to submit the form by doing:

document.querySelector('form[action*="/wp-admin/update.php?action=upload-plugin"]').submit()

I have also tried enabling the button manually and then clicking it via Javascript, but that has not worked either. Any ideas?

EDIT When trying to pull the outer HTML of the button, I typed the following into console:

console.log(document.querySelector('#install-plugin-submit').outerHTML)

The result of this code was the following:

<input type="submit" name="install-plugin-submit" id="install-plugin-submit" class="button" value="Install Now">
Argus Duong
  • 2,356
  • 1
  • 13
  • 24
Ethan
  • 1,905
  • 2
  • 21
  • 50
  • Are you talking about the 'Upload Plugin' or 'Install Now' button? Does either have a 'disabled' attribute? – Gopherkhan Mar 14 '17 at 18:53
  • @Gopherkhan The install now button – Ethan Mar 14 '17 at 20:40
  • Can you grab the button and log its outerHTML? – Gopherkhan Mar 14 '17 at 23:11
  • @Gopherkhan What do you mean by this? Like inspect the page, single out the button and share a screenshot or something? – Ethan Mar 14 '17 at 23:59
  • no, actually, more like console.log(document.querySelector('#your_button_id').outerHTML). I'm assuming there is some way to dump out logging from your phantom run – Gopherkhan Mar 15 '17 at 00:13
  • Also take a look at this question: http://stackoverflow.com/questions/25288307/phantomjs-and-clicking-a-form-button It's entirely possible that the buttons are being clicked, but you don't have a sufficient timeout to observe the result of that click. – Gopherkhan Mar 15 '17 at 21:32
  • @Gopherkhan check update, also I am not so concerned with observing the results, but instead I believe the script is trying to click the button before it can even detect a plugin has been loaded. – Ethan Mar 15 '17 at 23:03
  • I see I see. So, can you add a looping timeout to ensure that that portion of the dom exists before clicking the button? e.g., if the dom doesn't exist, set a timeout to check for it again.. if that doesn't work, try yet again. – Gopherkhan Mar 17 '17 at 22:03
  • I'm not exactly sure I would be able to accomplish that, mainly because if this looping timeout is apart of a nested function within a parent function that is controlled by a separate timeout value then it would be killed off regardless. Does that make sense? – Ethan Mar 17 '17 at 23:48
  • Excuse my simplistic question but what the point of doing this over uploading it over FTP/SFTP ? – Mathieu de Lorimier Mar 20 '17 at 23:30
  • Requires a new FTP account to be created, adds a ton of extra steps. This is the way it has to be – Ethan Mar 21 '17 at 02:39
  • I see there is no "disabled" attribute but please make sure it is not disabled by using document.querySelector('#install-plugin-submit').disabled = false and also check the value of the input: document.querySelector('#pluginzip').value – alireza Mar 21 '17 at 09:26
  • You might want to check out the following answers, if the element availability is the problem: http://stackoverflow.com/questions/16807212/how-to-wait-for-element-visibility-in-phantomjs – Gopherkhan Mar 21 '17 at 17:24
  • @alireza that query returns `false` – Ethan Mar 21 '17 at 20:13
  • The query "document.querySelector('#pluginzip').value" should return name of the file you attached or empty string "". How about "document.querySelector('#install-plugin-submit').disabled = false"? didn't enable the button? – alireza Mar 22 '17 at 10:50
  • If you're worried about the plugin not being uploaded yet, then can't you bind to the success function of the upload you're doing and run your submit there? If after that you have same result, try to debug the plugin installation process in a normal wordpress, inspect the form, button, try to update the file input from console, see if it enables the button, are there any more attributes added to the button etc. Simulate what your phantom is doing. – Martina Mar 23 '17 at 19:46
  • Would you mind posting some of the code, either for the UI or the test scripts? :) – Gopherkhan Mar 24 '17 at 00:12
  • I had a similiar issue with https://stackoverflow.com/questions/45439608/tricky-password-field-in-wordpress-install-script-using-codeception . In my case I'm pretty sure it was a JS issue, in that I was using PHP browser. Can you run the test with a full browser using Selenium? That would eleminate a lot of issues. – Jim Maguire Aug 12 '17 at 02:03

1 Answers1

1

How did you get the value into the file input box? Depending on the browser (client) implementation, simply adding text as the file input value likely will not trigger the box's change event.

The first (read: simplest) solution may be to try $('form.wp-upload-form input[type="file"]').trigger('change'); after you whack in the value. (If you're not using jQuery, see here on how to trigger a native event; it looks like you already know how to select nodes. PhantomJS may very well have a native trigger function because it's the kind of thing you do in that kind of application.)

Failing that, you may want to simply upload the file through JS. I'm on 4.7.3 and my form looks like this:

<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="http://[server]/wp-admin/update.php?action=upload-plugin"> <input type="hidden" id="_wpnonce" name="_wpnonce" value="[nonce]"><input type="hidden" name="_wp_http_referer" value="/wp-admin/plugin-install.php"> <label class="screen-reader-text" for="pluginzip">Plugin zip file</label> <input type="file" id="pluginzip" name="pluginzip"> <input type="submit" name="install-plugin-submit" id="install-plugin-submit" class="button" value="Install Now" disabled=""> </form>

Put together a FormData, scrape the submit URL from the action tag on the form, make sure you include the nonce and probably pass the submit value for good measure. Assembling a multipart/form-data POST is annoying without a suitable plugin but if you've gotten this far you've probably had to deal with more annoying stuff already.

WordPress shouldn't be able to tell the difference between what you submit from its own form or what you fake together and throw at the same URL. If it is, check the client string setting, make sure you've got the nonce right and make sure you're setting the referer [sic.] correctly.

Stephan Samuel
  • 648
  • 6
  • 12