max / alloy
1 file changed,
+13 insertions,
-2 deletions
| @@ -57,7 +57,17 @@ | |||
| 57 | 57 | # their own indented line, in the action color, between the prose above and the | |
| 58 | 58 | # field below. Anchored on the shape rather than on a line number, because the | |
| 59 | 59 | # prose around it is the part likely to be reworded. | |
| 60 | - | PHRASE = re.compile(r"^\s{2,}([a-z]+(?: [a-z]+){7})\s*$", re.M) | |
| 60 | + | # | |
| 61 | + | # The bounds are `[^A-Za-z]*` rather than `\s*` because this is read off a | |
| 62 | + | # rendered TUI and every line carries the pane's own border characters. A | |
| 63 | + | # whitespace-anchored pattern finds nothing here, which is a wrong answer that | |
| 64 | + | # looks like a missing phrase. | |
| 65 | + | PHRASE = re.compile(r"^[^A-Za-z]*([a-z]+(?: [a-z]+){7})[^A-Za-z]*$", re.M) | |
| 66 | + | ||
| 67 | + | # Where the phrase is, said in the prose above it. Searching after this rather | |
| 68 | + | # than over the whole screen keeps the pattern from matching an unlucky line of | |
| 69 | + | # lowercase prose somewhere else on the page. | |
| 70 | + | PHRASE_AFTER = "is not stored anywhere" | |
| 61 | 71 | ||
| 62 | 72 | ||
| 63 | 73 | def finish_encrypted(s, timeout): | |
| @@ -76,7 +86,8 @@ | |||
| 76 | 86 | screen = s.screen.text() | |
| 77 | 87 | check("Installation finished" in screen, | |
| 78 | 88 | "the recovery screen says the install did not finish", s) | |
| 79 | - | hit = PHRASE.search(screen) | |
| 89 | + | tail = screen.split(PHRASE_AFTER, 1)[-1] | |
| 90 | + | hit = PHRASE.search(tail) | |
| 80 | 91 | check(hit is not None, "no eight-word recovery phrase on the screen that asks for one", s) | |
| 81 | 92 | s.send(hit.group(1)) | |
| 82 | 93 | s.send(ENTER) |