Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when using installPlugin #186

Closed
johnhooks opened this issue Apr 6, 2023 · 12 comments
Closed

Error when using installPlugin #186

johnhooks opened this issue Apr 6, 2023 · 12 comments

Comments

@johnhooks
Copy link

johnhooks commented Apr 6, 2023

The problem

I received the following error when attempting to use the installPlugin function.

Uncaught (in promise) TypeError: Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'.

Some troubleshooting

The error originated from line 16:

const pluginFormPage = asDOM(pluginForm);
const pluginFormData = new FormData(
pluginFormPage.querySelector('.wp-upload-form')! as HTMLFormElement
) as any;

I checked the selectors, and they look right. Perhaps it is something wrong with the request in the following? I double checked the url and it works in a regular WordPress instance. But I am unfamiliar with how to debug a request through the ServiceWorker.

const pluginForm = await playground.request({
relativeUrl: '/wp-admin/plugin-install.php?tab=upload',
});

Additional information

This is the project in which I am getting the error. It's pretty simple, I'm just trying to figure out a bare minimum implementation of this to showcase a plugin in development.

https://github.com/johnhooks/playground-experiment

The current version of the site is hosted here if you want to examine the issue in the wild.

https://johnhooks.io/playground-experiment/

@adamziel
Copy link
Collaborator

adamziel commented Apr 11, 2023

Thank you for reporting @johnhooks! I agree – that error isn't very useful.

Most likely WordPress returned an error message after uploading the plugin zip files – perhaps there's something wrong with the bundle? You could log the HTML returned by WordPress with the following line added in install-plugin.ts:

	const pluginForm = await playground.request({
		relativeUrl: '/wp-admin/plugin-install.php?tab=upload',
	});
+	console.log( pluginForm.text );
	const pluginFormPage = asDOM(pluginForm);

Make sure you're on latest trunk and have the latest npm packages installed – I only added support for .text today, and unfortunately it was a breaking change. I hope to see less and less of these over time.

Thinking about the future, ideally the error would tell you exactly what went wrong and what to do next.

@johnhooks
Copy link
Author

I'll try the same steps from inside the playground repo.

What I was originally doing was use the playground client as a dependency in a totally separate project, rather than work from inside the playground repo. But I will try your suggestion and report back.

@adamziel
Copy link
Collaborator

Thanks! It's issues like this one that will eventually make for a developer experience that makes the client good enough to use without ever debugging anything directly in the repo 🙌

@johnhooks
Copy link
Author

johnhooks commented Apr 26, 2023

I tried this directly in the wordpress-playground repo and there wasn't an error. So there was something specific about this setup. @adamziel would you like to keep this issue open since there is something wrong when using installPlugin? I am willing to dig deeper, though I would need a little guidance on how to debugging from inside the iframe.

Edit: The error is happening in the client, I'll walk through with the debugger and find the response from the iframe, it should be informative.

@adamziel
Copy link
Collaborator

adamziel commented Apr 26, 2023

@johnhooks I've been rolling out major updates to that API over the last few days including a few today – maybe they fixed the problem here? 🤞 Here's the gist of it:

The installPlugin helper, for example, got a new signature:

installPlugin( playground, { "pluginZipFile": fileObject } );

@johnhooks
Copy link
Author

johnhooks commented Apr 26, 2023

@adamziel I saw that and tried it, but still had issues. I'll keep digging.

Edit: I'm going to try stripping everything out, and use just a bare HTML file like the main example in the docs.

@johnhooks
Copy link
Author

johnhooks commented Apr 26, 2023

BOOM! This worked!

@adamziel, are all the docs auto generated, or could you use a hand updating some of them? I was able to figure it out from reading the source, but the website docs were not at all helpful.

https://johnhooks.io/playground-experiment/

<!DOCTYPE html>
<html>
  <head>
    <title>WordPress Playground</title>
  </head>
  <body>
    <iframe id="wp" style="width: 1200px; height: 800px"></iframe>
    <script type="importmap">
      {
        "imports": {
          "@wp-playground/client": "https://unpkg.com/@wp-playground/client/index.js"
        }
      }
    </script>
    <script type="module">
      import {
        startPlaygroundWeb,
        installPlugin,
        login,
      } from "@wp-playground/client";

      main();

      async function main() {
        const playground = await startPlaygroundWeb({
          iframe: document.getElementById("wp"),
          remoteUrl: "https://playground.wordpress.net/remote.html",
        });

        await playground.isReady();

        await login(playground, { username: "admin", password: "password" });

        const pluginZipFile = await fetchPlugin();

        await installPlugin(playground, { pluginZipFile, activate: true });

        await playground.goTo("/wp-admin");
      }

      async function fetchPlugin() {
        const response = await fetch("/wp-feature-notifications.zip");
        const blob = await response.blob();
        const file = new File([blob], "wp-feature-notifications.zip");
        return file;
      }
    </script>
  </body>
</html>

@johnhooks
Copy link
Author

johnhooks commented Apr 26, 2023

I'm assuming a custom Blueprint would signal to the progress bar to keep going while installing the plugin? Because right now it's a little awkward to stall out on the homepage and then redirect to the /wp-admin once the plugin is installed and activated.

@johnhooks
Copy link
Author

johnhooks commented Apr 26, 2023

Okay after a bit more reading of #214 and #215, this is way cleaner. Thank you, this is really amazing.

async function main() {
  const response = await fetch("/wp-feature-notifications.zip");
  const blob = await response.blob();
  const pluginZipFile = new File([blob], "wp-feature-notifications.zip");
  const playground = await startPlaygroundWeb({
    iframe: document.getElementById("wp"),
    remoteUrl: "https://playground.wordpress.net/remote.html",
    blueprint: {
      landingPage: "/wp-admin/",
      preferredVersions: {
        php: "8.0",
        wp: "latest",
      },
      steps: [
        { step: "login", username: "admin", password: "password" },
        {
          step: "installPlugin",
          pluginZipFile,
        },
      ],
    },
  });
}

@adamziel
Copy link
Collaborator

adamziel commented Apr 27, 2023

Oh yay, this is amazing @johnhooks! I love the experiment page you shared – would it be okay to feature it as an example in Playground docs?

Also – did you ever find the problem with the original implementation? I wonder if there's anything to be fixed in Playground.

BTW your Blueprint could even declare the zip file as a resource and get additional progress reporting on the download:

async function main() {
  const playground = await startPlaygroundWeb({
    iframe: document.getElementById("wp"),
    remoteUrl: "https://playground.wordpress.net/remote.html",
    blueprint: {
      landingPage: "/wp-admin/",
      preferredVersions: {
        php: "8.0",
        wp: "latest",
      },
      steps: [
        { step: "login", username: "admin", password: "password" },
        {
          step: "installPlugin",
          pluginZipFile: {
            resource: "url",
            url: "/wp-feature-notifications.zip"
          },
        },
      ],
    },
  });
}

@adamziel, are all the docs auto generated, or could you use a hand updating some of them? I was able to figure it out from reading the source, but the website docs were not at all helpful.

I could certainly use a hand updating them, thank you for proposing!

The current doc is pretty stale as I've been laser focused on harmonizing the APIs to support the ongoing projects. Now is a great time to revisit the documentation! I just outlined some thoughts in #217 – you're more than welcome to join me there!

@johnhooks
Copy link
Author

@adamziel thanks for the tip, that's even better.

@johnhooks
Copy link
Author

Oh and absolutely that site could be used as an example, though it will eventually be hosted it under https://wordpress.github.io/wp-feature-notifications/. I just need to work out the details of how we are going to create a documentation site for the API, the Storybook, and now the Playground 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants