Konubinix' opinionated web of thoughts

Debug Cucumber Tests in Emacs

Fleeting

debug cucumber-js tests in emacs with dap-mode

test example

TMP="$(mktemp -d)"
trap "rm -rf '${TMP}'" 0
git clone https://github.com/cucumber/cucumber-js-examples "${TMP}"
Cloning into '/home/sam/tmp/tmp.xmxvENC75r'...
remote: Enumerating objects: 195, done.
remote: Counting objects:   4% (1/25)        
remote: Counting objects:   8% (2/25)        
remote: Counting objects:  12% (3/25)        
remote: Counting objects:  16% (4/25)        
remote: Counting objects:  20% (5/25)        
remote: Counting objects:  24% (6/25)        
remote: Counting objects:  28% (7/25)        
remote: Counting objects:  32% (8/25)        
remote: Counting objects:  36% (9/25)        
remote: Counting objects:  40% (10/25)        
remote: Counting objects:  44% (11/25)        
remote: Counting objects:  48% (12/25)        
remote: Counting objects:  52% (13/25)        
remote: Counting objects:  56% (14/25)        
remote: Counting objects:  60% (15/25)        
remote: Counting objects:  64% (16/25)        
remote: Counting objects:  68% (17/25)        
remote: Counting objects:  72% (18/25)        
remote: Counting objects:  76% (19/25)        
remote: Counting objects:  80% (20/25)        
remote: Counting objects:  84% (21/25)        
remote: Counting objects:  88% (22/25)        
remote: Counting objects:  92% (23/25)        
remote: Counting objects:  96% (24/25)        
remote: Counting objects: 100% (25/25)        
remote: Counting objects: 100% (25/25), done.
remote: Compressing objects:  10% (1/10)        
remote: Compressing objects:  20% (2/10)        
remote: Compressing objects:  30% (3/10)        
remote: Compressing objects:  40% (4/10)        
remote: Compressing objects:  50% (5/10)        
remote: Compressing objects:  60% (6/10)        
remote: Compressing objects:  70% (7/10)        
remote: Compressing objects:  80% (8/10)        
remote: Compressing objects:  90% (9/10)        
remote: Compressing objects: 100% (10/10)        
remote: Compressing objects: 100% (10/10), done.
Receiving objects:   0% (1/195)
Receiving objects:   1% (2/195)
Receiving objects:   2% (4/195)
Receiving objects:   3% (6/195)
Receiving objects:   4% (8/195)
Receiving objects:   5% (10/195)
Receiving objects:   6% (12/195)
Receiving objects:   7% (14/195)
Receiving objects:   8% (16/195)
Receiving objects:   9% (18/195)
Receiving objects:  10% (20/195)
Receiving objects:  11% (22/195)
Receiving objects:  12% (24/195)
Receiving objects:  13% (26/195)
Receiving objects:  14% (28/195)
Receiving objects:  15% (30/195)
Receiving objects:  16% (32/195)
Receiving objects:  17% (34/195)
Receiving objects:  18% (36/195)
Receiving objects:  19% (38/195)
Receiving objects:  20% (39/195)
Receiving objects:  21% (41/195)
Receiving objects:  22% (43/195)
Receiving objects:  23% (45/195)
Receiving objects:  24% (47/195)
Receiving objects:  25% (49/195)
Receiving objects:  26% (51/195)
Receiving objects:  27% (53/195)
Receiving objects:  28% (55/195)
Receiving objects:  29% (57/195)
Receiving objects:  30% (59/195)
Receiving objects:  31% (61/195)
Receiving objects:  32% (63/195)
Receiving objects:  33% (65/195)
Receiving objects:  34% (67/195)
Receiving objects:  35% (69/195)
Receiving objects:  36% (71/195)
Receiving objects:  37% (73/195)
Receiving objects:  38% (75/195)
Receiving objects:  39% (77/195)
Receiving objects:  40% (78/195)
Receiving objects:  41% (80/195)
Receiving objects:  42% (82/195)
Receiving objects:  43% (84/195)
Receiving objects:  44% (86/195)
Receiving objects:  45% (88/195)
Receiving objects:  46% (90/195)
Receiving objects:  47% (92/195)
Receiving objects:  48% (94/195)
Receiving objects:  49% (96/195)
Receiving objects:  50% (98/195)
Receiving objects:  51% (100/195)
Receiving objects:  52% (102/195)
Receiving objects:  53% (104/195)
Receiving objects:  54% (106/195)
Receiving objects:  55% (108/195)
Receiving objects:  56% (110/195)
Receiving objects:  57% (112/195)
Receiving objects:  58% (114/195)
Receiving objects:  59% (116/195)
Receiving objects:  60% (117/195)
Receiving objects:  61% (119/195)
Receiving objects:  62% (121/195)
Receiving objects:  63% (123/195)
Receiving objects:  64% (125/195)
Receiving objects:  65% (127/195)
Receiving objects:  66% (129/195)
Receiving objects:  67% (131/195)
Receiving objects:  68% (133/195)
Receiving objects:  69% (135/195)
Receiving objects:  70% (137/195)
Receiving objects:  71% (139/195)
Receiving objects:  72% (141/195)
Receiving objects:  73% (143/195)
Receiving objects:  74% (145/195)
Receiving objects:  75% (147/195)
Receiving objects:  76% (149/195)
Receiving objects:  77% (151/195)
Receiving objects:  78% (153/195)
Receiving objects:  79% (155/195)
Receiving objects:  80% (156/195)
Receiving objects:  81% (158/195)
Receiving objects:  82% (160/195)
Receiving objects:  83% (162/195)
Receiving objects:  84% (164/195)
Receiving objects:  85% (166/195)
Receiving objects:  86% (168/195)
Receiving objects:  87% (170/195)
Receiving objects:  88% (172/195)
Receiving objects:  89% (174/195)
Receiving objects:  90% (176/195)
Receiving objects:  91% (178/195)
Receiving objects:  92% (180/195)
Receiving objects:  93% (182/195)
Receiving objects:  94% (184/195)
Receiving objects:  95% (186/195)
Receiving objects:  96% (188/195)
remote: Total 195 (delta 16), reused 15 (delta 15), pack-reused 170
Receiving objects:  97% (190/195)
Receiving objects:  98% (192/195)
Receiving objects:  99% (194/195)
Receiving objects: 100% (195/195)
Receiving objects: 100% (195/195), 236.99 KiB | 955.00 KiB/s, done.
Resolving deltas:   0% (0/61)
Resolving deltas:   1% (1/61)
Resolving deltas:   3% (2/61)
Resolving deltas:   4% (3/61)
Resolving deltas:   6% (4/61)
Resolving deltas:   8% (5/61)
Resolving deltas:   9% (6/61)
Resolving deltas:  11% (7/61)
Resolving deltas:  13% (8/61)
Resolving deltas:  14% (9/61)
Resolving deltas:  16% (10/61)
Resolving deltas:  18% (11/61)
Resolving deltas:  19% (12/61)
Resolving deltas:  21% (13/61)
Resolving deltas:  22% (14/61)
Resolving deltas:  24% (15/61)
Resolving deltas:  26% (16/61)
Resolving deltas:  27% (17/61)
Resolving deltas:  29% (18/61)
Resolving deltas:  31% (19/61)
Resolving deltas:  32% (20/61)
Resolving deltas:  34% (21/61)
Resolving deltas:  36% (22/61)
Resolving deltas:  37% (23/61)
Resolving deltas:  39% (24/61)
Resolving deltas:  40% (25/61)
Resolving deltas:  42% (26/61)
Resolving deltas:  44% (27/61)
Resolving deltas:  45% (28/61)
Resolving deltas:  47% (29/61)
Resolving deltas:  49% (30/61)
Resolving deltas:  50% (31/61)
Resolving deltas:  52% (32/61)
Resolving deltas:  54% (33/61)
Resolving deltas:  55% (34/61)
Resolving deltas:  57% (35/61)
Resolving deltas:  59% (36/61)
Resolving deltas:  60% (37/61)
Resolving deltas:  62% (38/61)
Resolving deltas:  63% (39/61)
Resolving deltas:  65% (40/61)
Resolving deltas:  67% (41/61)
Resolving deltas:  68% (42/61)
Resolving deltas:  70% (43/61)
Resolving deltas:  72% (44/61)
Resolving deltas:  73% (45/61)
Resolving deltas:  75% (46/61)
Resolving deltas:  77% (47/61)
Resolving deltas:  78% (48/61)
Resolving deltas:  80% (49/61)
Resolving deltas:  81% (50/61)
Resolving deltas:  83% (51/61)
Resolving deltas:  85% (52/61)
Resolving deltas:  86% (53/61)
Resolving deltas:  88% (54/61)
Resolving deltas:  90% (55/61)
Resolving deltas:  91% (56/61)
Resolving deltas:  93% (57/61)
Resolving deltas:  95% (58/61)
Resolving deltas:  96% (59/61)
Resolving deltas:  98% (60/61)
Resolving deltas: 100% (61/61)
Resolving deltas: 100% (61/61), done.
cd "${TMP}/examples/command-line"
npm i
added 90 packages, and audited 91 packages in 6s

7 packages are looking for funding
  run `npm fund` for details

1 high severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
npm test
> command-line-cucumber-js-example@1.0.0 test
> cucumber-js

/home/sam/tmp/tmp.xmxvENC75r/examples/command-line/bin
greet hello
..

1 scenario (1 passed)
2 steps (2 passed)
0m00.251s (executing steps: 0m00.204s)

running with default dap-node (spoiler, it won’t work)

Getting into the step and adding a breakpoint

Then, using dap-node.

(load-library "dap-node")

It comes with a default “Node Run Configuration” template.

I need to extend it to tell the command to run and where to run the command from1.

{ “name”: “Launch dev acceptance tests”, “type”: “pwa-node”, “request”: “launch”, “program”: “\({workspaceRoot}/node_modules/.bin/cucumber-js”, “skipFiles”: [ “\){workspaceRoot}/node_modules/**/*.js” ], “cwd”: “${workspaceRoot}/test”, “args”: ["–tags", “@only”,"-p", “no_headless”, “–parallel”, “1”], },

(dap-register-debug-template "Debug the example"
                             (list :type "node"
                                   :cwd "${workspaceFolder}"
                                   :request "launch"
                                   :program (string-trim (shell-command-to-string "which npm"))
                                   :args ["test"]
                                   :name "Node::Run"))

Then, with the steps.js buffer open, dun

In the output buffer, I get

node --inspect-brk=44822 ../../../../n/bin/npm test
Starting inspector on 127.0.0.1:44822 failed: address already in use

This is likely due to the fact cucumber spawns children processes and the obsolete debugger ms-vscode.node-debug2.

using dap-js-debug from https://github.com/emacs-lsp/dap-mode/pull/736

See https://github.com/emacs-lsp/dap-mode/issues/369 for more information.

(load-library "dap-js-debug")

It will match the "type": "pwa-node", instead of "type": "node", (see pwa-node vs node type).

So we need to use another template (based on the one already given in dap-js-debug.el).

(dap-register-debug-template "Debug the template"
                             (list :type "pwa-node"
                                   :cwd "${workspaceFolder}"
                                   :request "launch"
                                   :program (string-trim (shell-command-to-string "which npm"))
                                   :args ["test"]
                                   :name "Node.js Launch Program"))

Now, it works great!

Notes linking here


  1. note that I can make use of the Visual Studio Code variables, but the likes of workspaceFolder will work only if lsp is enabled and the root it’s root is appropriate.

     ↩︎