diff --git a/tap-snapshots/test/lib/commands/run-script.js.test.cjs b/tap-snapshots/test/lib/commands/run-script.js.test.cjs
new file mode 100644
index 0000000000000..a013fce282dd9
--- /dev/null
+++ b/tap-snapshots/test/lib/commands/run-script.js.test.cjs
@@ -0,0 +1,277 @@
+/* IMPORTANT
+ * This snapshot file is auto-generated, but designed for humans.
+ * It should be checked into source control and tracked carefully.
+ * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
+ * Make sure to inspect the output below.  Do not ignore changes!
+ */
+'use strict'
+exports[`test/lib/commands/run-script.js TAP list scripts no args > basic report 1`] = `
+Lifecycle scripts included in x@1.2.3:
+  test
+    exit 2
+  start
+    node server.js
+  stop
+    node kill-server.js
+
+available via \`npm run-script\`:
+  preenv
+    echo before the env
+  postenv
+    echo after the env
+`
+
+exports[`test/lib/commands/run-script.js TAP list scripts parseable > must match snapshot 1`] = `
+test:exit 2
+start:node server.js
+stop:node kill-server.js
+preenv:echo before the env
+postenv:echo after the env
+`
+
+exports[`test/lib/commands/run-script.js TAP list scripts warn json > json report 1`] = `
+{
+  "test": "exit 2",
+  "start": "node server.js",
+  "stop": "node kill-server.js",
+  "preenv": "echo before the env",
+  "postenv": "echo after the env"
+}
+`
+
+exports[`test/lib/commands/run-script.js TAP list scripts, only commands > must match snapshot 1`] = `
+Lifecycle scripts included in x@1.2.3:
+  preversion
+    echo doing the version dance
+`
+
+exports[`test/lib/commands/run-script.js TAP list scripts, only non-commands > must match snapshot 1`] = `
+Scripts available in x@1.2.3 via \`npm run-script\`:
+  glorp
+    echo doing the glerp glop
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces failed workspace run with succeeded runs > should log error msgs for each workspace script 1`] = `
+Lifecycle script \`glorp\` failed with error:
+Error: ERR
+  in workspace: a@1.0.0
+  at location: {CWD}/prefix/packages/a
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list all scripts --json > must match snapshot 1`] = `
+{
+  "a": {
+    "glorp": "echo a doing the glerp glop"
+  },
+  "b": {
+    "glorp": "echo b doing the glerp glop"
+  },
+  "c": {
+    "test": "exit 0",
+    "posttest": "echo posttest",
+    "lorem": "echo c lorem"
+  },
+  "d": {
+    "test": "exit 0",
+    "posttest": "echo posttest"
+  },
+  "e": {
+    "test": "exit 0",
+    "start": "echo start something"
+  },
+  "noscripts": {}
+}
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list all scripts --parseable > must match snapshot 1`] = `
+a:glorp:echo a doing the glerp glop
+b:glorp:echo b doing the glerp glop
+c:test:exit 0
+c:posttest:echo posttest
+c:lorem:echo c lorem
+d:test:exit 0
+d:posttest:echo posttest
+e:test:exit 0
+e:start:echo start something
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list all scripts > must match snapshot 1`] = `
+Scripts available in a@1.0.0 via \`npm run-script\`:
+  glorp
+    echo a doing the glerp glop
+
+Scripts available in b@2.0.0 via \`npm run-script\`:
+  glorp
+    echo b doing the glerp glop
+
+Lifecycle scripts included in c@1.0.0:
+  test
+    exit 0
+  posttest
+    echo posttest
+
+available via \`npm run-script\`:
+  lorem
+    echo c lorem
+
+Lifecycle scripts included in d@1.0.0:
+  test
+    exit 0
+  posttest
+    echo posttest
+
+Lifecycle scripts included in e:
+  test
+    exit 0
+  start
+    echo start something
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list all scripts with colors > must match snapshot 1`] = `
+Scripts available in a@1.0.0 via \`npm run-script\`:
+  glorp
+    echo a doing the glerp glop
+
+Scripts available in b@2.0.0 via \`npm run-script\`:
+  glorp
+    echo b doing the glerp glop
+
+Lifecycle scripts included in c@1.0.0:
+  test
+    exit 0
+  posttest
+    echo posttest
+
+available via \`npm run-script\`:
+  lorem
+    echo c lorem
+
+Lifecycle scripts included in d@1.0.0:
+  test
+    exit 0
+  posttest
+    echo posttest
+
+Lifecycle scripts included in e:
+  test
+    exit 0
+  start
+    echo start something
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by name > must match snapshot 1`] = `
+Scripts available in a@1.0.0 via \`npm run-script\`:
+  glorp
+    echo a doing the glerp glop
+
+Scripts available in b@2.0.0 via \`npm run-script\`:
+  glorp
+    echo b doing the glerp glop
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by parent folder > must match snapshot 1`] = `
+Scripts available in a@1.0.0 via \`npm run-script\`:
+  glorp
+    echo a doing the glerp glop
+
+Scripts available in b@2.0.0 via \`npm run-script\`:
+  glorp
+    echo b doing the glerp glop
+
+Lifecycle scripts included in c@1.0.0:
+  test
+    exit 0
+  posttest
+    echo posttest
+
+available via \`npm run-script\`:
+  lorem
+    echo c lorem
+
+Lifecycle scripts included in d@1.0.0:
+  test
+    exit 0
+  posttest
+    echo posttest
+
+Lifecycle scripts included in e:
+  test
+    exit 0
+  start
+    echo start something
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by path > must match snapshot 1`] = `
+Scripts available in a@1.0.0 via \`npm run-script\`:
+  glorp
+    echo a doing the glerp glop
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces missing scripts in all workspaces > should log error msgs for each workspace script 1`] = `
+Lifecycle script \`missing-script\` failed with error:
+Error: Missing script: "missing-script"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: a@1.0.0
+  at location: {CWD}/prefix/packages/a
+Lifecycle script \`missing-script\` failed with error:
+Error: Missing script: "missing-script"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: b@2.0.0
+  at location: {CWD}/prefix/packages/b
+Lifecycle script \`missing-script\` failed with error:
+Error: Missing script: "missing-script"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: c@1.0.0
+  at location: {CWD}/prefix/packages/c
+Lifecycle script \`missing-script\` failed with error:
+Error: Missing script: "missing-script"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: d@1.0.0
+  at location: {CWD}/prefix/packages/d
+Lifecycle script \`missing-script\` failed with error:
+Error: Missing script: "missing-script"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: e
+  at location: {CWD}/prefix/packages/e
+Lifecycle script \`missing-script\` failed with error:
+Error: Missing script: "missing-script"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: noscripts@1.0.0
+  at location: {CWD}/prefix/packages/noscripts
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces missing scripts in some workspaces > should log error msgs for each workspace script 1`] = `
+Lifecycle script \`test\` failed with error:
+Error: Missing script: "test"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: a@1.0.0
+  at location: {CWD}/prefix/packages/a
+Lifecycle script \`test\` failed with error:
+Error: Missing script: "test"
+
+To see a list of scripts, run:
+  npm run
+  in workspace: b@2.0.0
+  at location: {CWD}/prefix/packages/b
+`
+
+exports[`test/lib/commands/run-script.js TAP workspaces single failed workspace run > should log error msgs for each workspace script 1`] = `
+Lifecycle script \`test\` failed with error:
+Error: err
+  in workspace: c@1.0.0
+  at location: {CWD}/prefix/packages/c
+`
diff --git a/test/lib/commands/run-script.js b/test/lib/commands/run-script.js
index c5bb2b488c053..5009f13205747 100644
--- a/test/lib/commands/run-script.js
+++ b/test/lib/commands/run-script.js
@@ -30,7 +30,7 @@ const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => {
     ...mock,
     RUN_SCRIPTS: () => RUN_SCRIPTS,
     runScript: mock['run-script'],
-    cleanLogs: () => mock.logs.error.map(cleanCwd),
+    cleanLogs: () => mock.logs.error.map(cleanCwd).join('\n'),
   }
 }
 
@@ -418,50 +418,31 @@ t.test('list scripts', async t => {
 
     await mock.runScript.exec([])
 
-    return mock.outputs
+    return mock.joinedOutput()
   }
 
   t.test('no args', async t => {
     const output = await mockList(t)
-    t.strictSame(
-      output,
-      [
-        'Lifecycle scripts included in x@1.2.3:',
-        '  test\n    exit 2',
-        '  start\n    node server.js',
-        '  stop\n    node kill-server.js',
-        '\navailable via `npm run-script`:',
-        '  preenv\n    echo before the env',
-        '  postenv\n    echo after the env',
-        '',
-      ],
-      'basic report'
-    )
+    t.matchSnapshot(output, 'basic report')
   })
 
   t.test('silent', async t => {
-    const outputs = await mockList(t, { silent: true })
-    t.strictSame(outputs, [])
+    const output = await mockList(t, { silent: true })
+    t.strictSame(output, '')
   })
   t.test('warn json', async t => {
-    const outputs = await mockList(t, { json: true })
-    t.strictSame(outputs, [JSON.stringify(scripts, 0, 2)], 'json report')
+    const output = await mockList(t, { json: true })
+    t.matchSnapshot(output, 'json report')
   })
 
   t.test('parseable', async t => {
-    const outputs = await mockList(t, { parseable: true })
-    t.strictSame(outputs, [
-      'test:exit 2',
-      'start:node server.js',
-      'stop:node kill-server.js',
-      'preenv:echo before the env',
-      'postenv:echo after the env',
-    ])
+    const output = await mockList(t, { parseable: true })
+    t.matchSnapshot(output)
   })
 })
 
 t.test('list scripts when no scripts', async t => {
-  const { runScript, outputs } = await mockRs(t, {
+  const { runScript, joinedOutput } = await mockRs(t, {
     prefixDir: {
       'package.json': JSON.stringify({
         name: 'x',
@@ -471,11 +452,11 @@ t.test('list scripts when no scripts', async t => {
   })
 
   await runScript.exec([])
-  t.strictSame(outputs, [], 'nothing to report')
+  t.strictSame(joinedOutput(), '', 'nothing to report')
 })
 
 t.test('list scripts, only commands', async t => {
-  const { runScript, outputs } = await mockRs(t, {
+  const { runScript, joinedOutput } = await mockRs(t, {
     prefixDir: {
       'package.json': JSON.stringify({
         name: 'x',
@@ -486,15 +467,11 @@ t.test('list scripts, only commands', async t => {
   })
 
   await runScript.exec([])
-  t.strictSame(outputs, [
-    'Lifecycle scripts included in x@1.2.3:',
-    '  preversion\n    echo doing the version dance',
-    '',
-  ])
+  t.matchSnapshot(joinedOutput())
 })
 
 t.test('list scripts, only non-commands', async t => {
-  const { runScript, outputs } = await mockRs(t, {
+  const { runScript, joinedOutput } = await mockRs(t, {
     prefixDir: {
       'package.json': JSON.stringify({
         name: 'x',
@@ -505,11 +482,7 @@ t.test('list scripts, only non-commands', async t => {
   })
 
   await runScript.exec([])
-  t.strictSame(outputs, [
-    'Scripts available in x@1.2.3 via `npm run-script`:',
-    '  glorp\n    echo doing the glerp glop',
-    '',
-  ])
+  t.matchSnapshot(joinedOutput())
 })
 
 t.test('workspaces', async t => {
@@ -590,154 +563,43 @@ t.test('workspaces', async t => {
   }
 
   t.test('list all scripts', async t => {
-    const { outputs } = await mockWorkspaces(t)
-    t.strictSame(outputs, [
-      'Scripts available in a@1.0.0 via `npm run-script`:',
-      '  glorp\n    echo a doing the glerp glop',
-      '',
-      'Scripts available in b@2.0.0 via `npm run-script`:',
-      '  glorp\n    echo b doing the glerp glop',
-      '',
-      'Lifecycle scripts included in c@1.0.0:',
-      '  test\n    exit 0',
-      '  posttest\n    echo posttest',
-      '\navailable via `npm run-script`:',
-      '  lorem\n    echo c lorem',
-      '',
-      'Lifecycle scripts included in d@1.0.0:',
-      '  test\n    exit 0',
-      '  posttest\n    echo posttest',
-      '',
-      'Lifecycle scripts included in e:',
-      '  test\n    exit 0',
-      '  start\n    echo start something',
-      '',
-    ])
+    const { joinedOutput } = await mockWorkspaces(t)
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list regular scripts, filtered by name', async t => {
-    const { outputs } = await mockWorkspaces(t, { workspaces: ['a', 'b'] })
-    t.strictSame(outputs, [
-      'Scripts available in a@1.0.0 via `npm run-script`:',
-      '  glorp\n    echo a doing the glerp glop',
-      '',
-      'Scripts available in b@2.0.0 via `npm run-script`:',
-      '  glorp\n    echo b doing the glerp glop',
-      '',
-    ])
+    const { joinedOutput } = await mockWorkspaces(t, { workspaces: ['a', 'b'] })
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list regular scripts, filtered by path', async t => {
-    const { outputs } = await mockWorkspaces(t, { workspaces: ['./packages/a'] })
-    t.strictSame(outputs, [
-      'Scripts available in a@1.0.0 via `npm run-script`:',
-      '  glorp\n    echo a doing the glerp glop',
-      '',
-    ])
+    const { joinedOutput } = await mockWorkspaces(t, { workspaces: ['./packages/a'] })
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list regular scripts, filtered by parent folder', async t => {
-    const { outputs } = await mockWorkspaces(t, { workspaces: ['./packages'] })
-    t.strictSame(outputs, [
-      'Scripts available in a@1.0.0 via `npm run-script`:',
-      '  glorp\n    echo a doing the glerp glop',
-      '',
-      'Scripts available in b@2.0.0 via `npm run-script`:',
-      '  glorp\n    echo b doing the glerp glop',
-      '',
-      'Lifecycle scripts included in c@1.0.0:',
-      '  test\n    exit 0',
-      '  posttest\n    echo posttest',
-      '\navailable via `npm run-script`:',
-      '  lorem\n    echo c lorem',
-      '',
-      'Lifecycle scripts included in d@1.0.0:',
-      '  test\n    exit 0',
-      '  posttest\n    echo posttest',
-      '',
-      'Lifecycle scripts included in e:',
-      '  test\n    exit 0',
-      '  start\n    echo start something',
-      '',
-    ])
+    const { joinedOutput } = await mockWorkspaces(t, { workspaces: ['./packages'] })
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list all scripts with colors', async t => {
-    const { outputs } = await mockWorkspaces(t, { color: 'always' })
-    t.strictSame(outputs, [
-      /* eslint-disable-next-line max-len */
-      '\u001b[1mScripts\u001b[22m available in \x1B[32ma@1.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:',
-      '  glorp\n    \x1B[2mecho a doing the glerp glop\x1B[22m',
-      '',
-      /* eslint-disable-next-line max-len */
-      '\u001b[1mScripts\u001b[22m available in \x1B[32mb@2.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:',
-      '  glorp\n    \x1B[2mecho b doing the glerp glop\x1B[22m',
-      '',
-      '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32mc@1.0.0\x1B[39m:',
-      '  test\n    \x1B[2mexit 0\x1B[22m',
-      '  posttest\n    \x1B[2mecho posttest\x1B[22m',
-      '\navailable via `\x1B[34mnpm run-script\x1B[39m`:',
-      '  lorem\n    \x1B[2mecho c lorem\x1B[22m',
-      '',
-      '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32md@1.0.0\x1B[39m:',
-      '  test\n    \x1B[2mexit 0\x1B[22m',
-      '  posttest\n    \x1B[2mecho posttest\x1B[22m',
-      '',
-      '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32me\x1B[39m:',
-      '  test\n    \x1B[2mexit 0\x1B[22m',
-      '  start\n    \x1B[2mecho start something\x1B[22m',
-      '',
-    ])
+    const { joinedOutput } = await mockWorkspaces(t, { color: 'always' })
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list all scripts --json', async t => {
-    const { outputs } = await mockWorkspaces(t, { json: true })
-    t.strictSame(outputs, [
-
-      '{\n' +
-          '  "a": {\n' +
-          '    "glorp": "echo a doing the glerp glop"\n' +
-          '  },\n' +
-          '  "b": {\n' +
-          '    "glorp": "echo b doing the glerp glop"\n' +
-          '  },\n' +
-          '  "c": {\n' +
-          '    "test": "exit 0",\n' +
-          '    "posttest": "echo posttest",\n' +
-          '    "lorem": "echo c lorem"\n' +
-          '  },\n' +
-          '  "d": {\n' +
-          '    "test": "exit 0",\n' +
-          '    "posttest": "echo posttest"\n' +
-          '  },\n' +
-          '  "e": {\n' +
-          '    "test": "exit 0",\n' +
-          '    "start": "echo start something"\n' +
-          '  },\n' +
-          '  "noscripts": {}\n' +
-          '}',
-
-    ])
+    const { joinedOutput } = await mockWorkspaces(t, { json: true })
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list all scripts --parseable', async t => {
-    const { outputs } = await mockWorkspaces(t, { parseable: true })
-    t.strictSame(outputs, [
-      'a:glorp:echo a doing the glerp glop',
-      'b:glorp:echo b doing the glerp glop',
-      'c:test:exit 0',
-      'c:posttest:echo posttest',
-      'c:lorem:echo c lorem',
-      'd:test:exit 0',
-      'd:posttest:echo posttest',
-      'e:test:exit 0',
-      'e:start:echo start something',
-    ])
+    const { joinedOutput } = await mockWorkspaces(t, { parseable: true })
+    t.matchSnapshot(joinedOutput())
   })
 
   t.test('list no scripts --loglevel=silent', async t => {
-    const { outputs } = await mockWorkspaces(t, { silent: true })
-    t.strictSame(outputs, [])
+    const { joinedOutput } = await mockWorkspaces(t, { silent: true })
+    t.strictSame(joinedOutput(), '')
   })
 
   t.test('run scripts across all workspaces', async t => {
@@ -777,34 +639,8 @@ t.test('workspaces', async t => {
 
     await runScript.exec(['missing-script'])
     t.match(RUN_SCRIPTS(), [])
-    t.strictSame(
+    t.matchSnapshot(
       cleanLogs(),
-      [
-        'Lifecycle script `missing-script` failed with error:',
-        'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: a@1.0.0',
-        '  at location: {CWD}/prefix/packages/a',
-        'Lifecycle script `missing-script` failed with error:',
-        'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: b@2.0.0',
-        '  at location: {CWD}/prefix/packages/b',
-        'Lifecycle script `missing-script` failed with error:',
-        'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: c@1.0.0',
-        '  at location: {CWD}/prefix/packages/c',
-        'Lifecycle script `missing-script` failed with error:',
-        'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: d@1.0.0',
-        '  at location: {CWD}/prefix/packages/d',
-        'Lifecycle script `missing-script` failed with error:',
-        'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: e',
-        '  at location: {CWD}/prefix/packages/e',
-        'Lifecycle script `missing-script` failed with error:',
-        'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: noscripts@1.0.0',
-        '  at location: {CWD}/prefix/packages/noscripts',
-      ],
       'should log error msgs for each workspace script'
     )
   })
@@ -816,18 +652,8 @@ t.test('workspaces', async t => {
     })
 
     t.match(RUN_SCRIPTS(), [])
-    t.strictSame(
+    t.matchSnapshot(
       cleanLogs(),
-      [
-        'Lifecycle script `test` failed with error:',
-        'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: a@1.0.0',
-        '  at location: {CWD}/prefix/packages/a',
-        'Lifecycle script `test` failed with error:',
-        'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n  npm run',
-        '  in workspace: b@2.0.0',
-        '  at location: {CWD}/prefix/packages/b',
-      ],
       'should log error msgs for each workspace script'
     )
   })
@@ -864,14 +690,8 @@ t.test('workspaces', async t => {
       workspaces: ['c'],
     })
 
-    t.strictSame(
+    t.matchSnapshot(
       cleanLogs(),
-      [
-        'Lifecycle script `test` failed with error:',
-        'Error: err',
-        '  in workspace: c@1.0.0',
-        '  at location: {CWD}/prefix/packages/c',
-      ],
       'should log error msgs for each workspace script'
     )
   })
@@ -887,14 +707,8 @@ t.test('workspaces', async t => {
       workspaces: ['a', 'b'],
     })
 
-    t.strictSame(
+    t.matchSnapshot(
       cleanLogs(),
-      [
-        'Lifecycle script `glorp` failed with error:',
-        'Error: ERR',
-        '  in workspace: a@1.0.0',
-        '  at location: {CWD}/prefix/packages/a',
-      ],
       'should log error msgs for each workspace script'
     )