diff --git a/package_manager/src/Stage.php b/package_manager/src/Stage.php
index 6548db10cf65b6addb8f6a034aa38ec1273394fb..4432089cd00f7d45e4ebe0271a7d1beee31bcedd 100644
--- a/package_manager/src/Stage.php
+++ b/package_manager/src/Stage.php
@@ -238,14 +238,15 @@ class Stage {
   public function require(array $constraints, bool $dev = FALSE): void {
     $this->checkOwnership();
 
-    $command = array_merge(['require'], $constraints);
-    $command[] = '--update-with-all-dependencies';
+    $command = array_merge(['require', '--no-update'], $constraints);
     if ($dev) {
       $command[] = '--dev';
     }
 
     $this->dispatch(new PreRequireEvent($this));
-    $this->stager->stage($command, $this->getStageDirectory());
+    $dir = $this->getStageDirectory();
+    $this->stager->stage($command, $dir);
+    $this->stager->stage(['update', '--with-all-dependencies'], $dir);
     $this->dispatch(new PostRequireEvent($this));
   }
 
diff --git a/package_manager/tests/src/Functional/ExcludedPathsTest.php b/package_manager/tests/src/Functional/ExcludedPathsTest.php
index dbc3dab973c07705b9ff8d754363a3c1f8ee6aed..184c36206eea67165596b009bba1a8873c6bb44c 100644
--- a/package_manager/tests/src/Functional/ExcludedPathsTest.php
+++ b/package_manager/tests/src/Functional/ExcludedPathsTest.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\Tests\package_manager\Functional;
 
-use Drupal\Core\Database\Driver\sqlite\Connection;
+use Drupal\Core\Database\Connection;
 use Drupal\Core\Site\Settings;
 use Drupal\package_manager\PathLocator;
 use Drupal\package_manager\Stage;
diff --git a/package_manager/tests/src/Kernel/ExcludedPathsSubscriberTest.php b/package_manager/tests/src/Kernel/ExcludedPathsSubscriberTest.php
index 538232d5b57e8293b321f168118adc9009bf1350..0489ad421300185aa4222b188dd7a3172fbefe5f 100644
--- a/package_manager/tests/src/Kernel/ExcludedPathsSubscriberTest.php
+++ b/package_manager/tests/src/Kernel/ExcludedPathsSubscriberTest.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\Tests\package_manager\Kernel;
 
-use Drupal\Core\Database\Driver\sqlite\Connection;
+use Drupal\Core\Database\Connection;
 use Drupal\package_manager\Event\PreCreateEvent;
 use Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber;
 
diff --git a/tests/src/Build/TemplateProjectSiteTestBase.php b/tests/src/Build/TemplateProjectSiteTestBase.php
index a05c5cd98de022ca892d4ce905fadeb861af6471..f77f19f2b3508b67d830cb48cd417ad924d6c7ec 100644
--- a/tests/src/Build/TemplateProjectSiteTestBase.php
+++ b/tests/src/Build/TemplateProjectSiteTestBase.php
@@ -45,6 +45,16 @@ abstract class TemplateProjectSiteTestBase extends QuickStartTestBase {
     $this->runComposer('composer remove --no-update drupal/automatic_updates', 'composer/Metapackage/CoreRecommended');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getCodebaseFinder() {
+    // If core's npm dependencies are installed, we don't want them to be
+    // included in the upstream version of core that gets installed into the
+    // test site.
+    return parent::getCodebaseFinder()->notPath('#^core/node_modules#');
+  }
+
   /**
    * Returns the full path to the test site's document root.
    *
diff --git a/tests/src/Build/UpdateTestBase.php b/tests/src/Build/UpdateTestBase.php
index 907acead16dba817590e0163eedf31016f789994..0af9c56922b549a50cc9d59a4c53e8a3dda30177 100644
--- a/tests/src/Build/UpdateTestBase.php
+++ b/tests/src/Build/UpdateTestBase.php
@@ -36,7 +36,9 @@ abstract class UpdateTestBase extends TemplateProjectSiteTestBase {
     // symlinked.
     $dir = 'project';
     $this->runComposer('composer config repo.automatic_updates path ' . __DIR__ . '/../../..', $dir);
-    $this->assertStringNotContainsString('Symlinking', $this->runComposer('COMPOSER_MIRROR_PATH_REPOS=1 composer require "drupal/automatic_updates:@dev"', $dir));
+    $this->runComposer('composer require --no-update "drupal/automatic_updates:@dev"', $dir);
+    $output = $this->runComposer('COMPOSER_MIRROR_PATH_REPOS=1 composer update --with-all-dependencies', $dir);
+    $this->assertStringNotContainsString('Symlinking', $output);
 
     // Install Drupal. Always allow test modules to be installed in the UI and,
     // for easier debugging, always display errors in their dubious glory.
diff --git a/tests/src/Functional/UpdaterFormTest.php b/tests/src/Functional/UpdaterFormTest.php
index 4ce78c89945f9e10bc62d484e08d163b8ae06317..f8e289ae21fa0b0ff14f3f58c5c4696cc49da071 100644
--- a/tests/src/Functional/UpdaterFormTest.php
+++ b/tests/src/Functional/UpdaterFormTest.php
@@ -282,7 +282,10 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
 
     /** @var \Drupal\package_manager_bypass\InvocationRecorderBase $stager */
     $stager = $this->container->get('package_manager.stager');
-    $this->assertCount($attempted_times, $stager->getInvocationArguments());
+    // If an update was attempted, then there will be two calls to the stager:
+    // one to change the constraints in composer.json, and another to actually
+    // update the installed dependencies.
+    $this->assertCount($attempted_times * 2, $stager->getInvocationArguments());
 
     /** @var \Drupal\package_manager_bypass\InvocationRecorderBase $committer */
     $committer = $this->container->get('package_manager.committer');
diff --git a/tests/src/Kernel/CronUpdaterTest.php b/tests/src/Kernel/CronUpdaterTest.php
index 413e42fbfe5f28fe44560b1ae33bfe928dfdf4fb..efed1a66738b89473e12ee04e0dfc116b3a1e2aa 100644
--- a/tests/src/Kernel/CronUpdaterTest.php
+++ b/tests/src/Kernel/CronUpdaterTest.php
@@ -110,7 +110,10 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase {
 
     $will_update = (int) $will_update;
     $this->assertCount($will_update, $this->container->get('package_manager.beginner')->getInvocationArguments());
-    $this->assertCount($will_update, $this->container->get('package_manager.stager')->getInvocationArguments());
+    // If updates happen, then there will be two calls to the stager: one to
+    // change the constraints in composer.json, and another to actually update
+    // the installed dependencies.
+    $this->assertCount($will_update * 2, $this->container->get('package_manager.stager')->getInvocationArguments());
     $this->assertCount($will_update, $this->container->get('package_manager.committer')->getInvocationArguments());
   }
 
diff --git a/tests/src/Kernel/UpdaterTest.php b/tests/src/Kernel/UpdaterTest.php
index 5881d851444a78ba6debfb81ddfede9884ba3a2b..d8d9c4a2a2f58d957898938283b7c6e3303a4046 100644
--- a/tests/src/Kernel/UpdaterTest.php
+++ b/tests/src/Kernel/UpdaterTest.php
@@ -75,26 +75,29 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
     // The production dependencies should be updated first...
     $expected_require_arguments = [
       'require',
+      '--no-update',
       'drupal/core-recommended:9.8.1',
-      '--update-with-all-dependencies',
     ];
     // ...followed by the dev dependencies.
     $expected_require_dev_arguments = [
       'require',
+      '--no-update',
       'drupal/core-dev:9.8.1',
-      '--update-with-all-dependencies',
       '--dev',
     ];
+    // In both cases, `composer update` will be called separately.
+    $expected_update_arguments = ['update', '--with-all-dependencies'];
+
     $this->container->get('automatic_updates.updater')->claim($id)->stage();
 
     /** @var \Drupal\package_manager_bypass\InvocationRecorderBase $stager */
     $stager = $this->container->get('package_manager.stager');
-    [
-      $actual_require_arguments,
-      $actual_require_dev_arguments,
-    ] = $stager->getInvocationArguments();
-    $this->assertSame($expected_require_arguments, $actual_require_arguments[0]);
-    $this->assertSame($expected_require_dev_arguments, $actual_require_dev_arguments[0]);
+    $invocation_arguments = $stager->getInvocationArguments();
+    $this->assertCount(4, $invocation_arguments);
+    $this->assertSame($expected_require_arguments, $invocation_arguments[0][0]);
+    $this->assertSame($expected_update_arguments, $invocation_arguments[1][0]);
+    $this->assertSame($expected_require_dev_arguments, $invocation_arguments[2][0]);
+    $this->assertSame($expected_update_arguments, $invocation_arguments[3][0]);
   }
 
   /**