| 91 | } |
| 92 | |
| 93 | async healStep(failedStep, error, failureContext = {}) { |
| 94 | output.debug(`Trying to heal ${failedStep.toCode()} step`) |
| 95 | |
| 96 | Object.assign(failureContext, { |
| 97 | error, |
| 98 | step: failedStep, |
| 99 | prevSteps: failureContext?.test?.steps?.slice(0, -1) || [], |
| 100 | }) |
| 101 | |
| 102 | const suggestions = await this.getCodeSuggestions(failureContext) |
| 103 | |
| 104 | if (suggestions.length === 0) { |
| 105 | debug('No healing suggestions found') |
| 106 | throw error |
| 107 | } |
| 108 | |
| 109 | output.debug(`Received ${suggestions.length} suggestion${suggestions.length === 1 ? '' : 's'}`) |
| 110 | |
| 111 | debug(suggestions) |
| 112 | |
| 113 | for (const suggestion of suggestions) { |
| 114 | for (const codeSnippet of suggestion.snippets) { |
| 115 | try { |
| 116 | debug('Executing', codeSnippet) |
| 117 | recorder.catch(e => { |
| 118 | debug(e) |
| 119 | }) |
| 120 | |
| 121 | if (typeof codeSnippet === 'string') { |
| 122 | const I = container.support('I') |
| 123 | await eval(codeSnippet) |
| 124 | } else if (typeof codeSnippet === 'function') { |
| 125 | await codeSnippet(container.support()) |
| 126 | } |
| 127 | |
| 128 | this.fixes.push({ |
| 129 | recipe: suggestion.name, |
| 130 | test: failureContext?.test, |
| 131 | step: failedStep, |
| 132 | snippet: codeSnippet, |
| 133 | }) |
| 134 | |
| 135 | if (failureContext?.test) { |
| 136 | const test = failureContext.test |
| 137 | let note = `This test was healed by '${suggestion.name}'` |
| 138 | note += `\n\nReplace the failed code:\n\n` |
| 139 | note += colors.red(`- ${failedStep.toCode()}\n`) |
| 140 | note += colors.green(`+ ${codeSnippet}\n`) |
| 141 | test.addNote('heal', note) |
| 142 | test.meta.healed = true |
| 143 | } |
| 144 | |
| 145 | recorder.add('healed', () => output.print(colors.bold.green(` Code healed successfully by ${suggestion.name}`), colors.gray('(no errors thrown)'))) |
| 146 | this.numHealed++ |
| 147 | // recorder.session.restore(); |
| 148 | return |
| 149 | } catch (err) { |
| 150 | debug('Failed to execute code', err) |