From cc0a663d0837cc5c6af25ad1349017cba6ceae9c Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Fri, 17 Jul 2026 17:08:38 +0100 Subject: [PATCH 1/2] messagix/bloks: add nil checks to `FindDescendant(s)` --- pkg/messagix/bloks/selenium.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/messagix/bloks/selenium.go b/pkg/messagix/bloks/selenium.go index f22dfaa9..4c5f8e3e 100644 --- a/pkg/messagix/bloks/selenium.go +++ b/pkg/messagix/bloks/selenium.go @@ -89,6 +89,9 @@ func (btn *BloksTreeNode) FindDescendants(pred func(*BloksTreeComponent) bool) [ } func (comp *BloksTreeComponent) FindDescendant(pred func(*BloksTreeComponent) bool) *BloksTreeComponent { + if comp == nil { + return nil + } if pred(comp) { return comp } @@ -101,6 +104,9 @@ func (comp *BloksTreeComponent) FindDescendant(pred func(*BloksTreeComponent) bo } func (comp *BloksTreeComponent) FindDescendants(pred func(*BloksTreeComponent) bool) []*BloksTreeComponent { + if comp == nil { + return nil + } if pred(comp) { return []*BloksTreeComponent{comp} } From 90767a866cb2991fd75e79d5c38c705e2dde3db5 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Fri, 17 Jul 2026 17:14:24 +0100 Subject: [PATCH 2/2] messagix/bloks: handle single continue MFA flow Debug payloads show a variant on the MFA page that does not present a list of options just a "continue" / "try another way" selector. --- pkg/messagix/bloks/selenium.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pkg/messagix/bloks/selenium.go b/pkg/messagix/bloks/selenium.go index 4c5f8e3e..13084fc7 100644 --- a/pkg/messagix/bloks/selenium.go +++ b/pkg/messagix/bloks/selenium.go @@ -1097,9 +1097,24 @@ func (b *Browser) DoLoginStep(ctx context.Context, userInput map[string]string) "Verify with Google": false, } - listItems := b.CurrentPage.FindDescendant(FilterByAttribute( + listHeader := b.CurrentPage.FindDescendant(FilterByAttribute( "bk.data.TextSpan", "text", "Choose a way to confirm it’s you", - )). + )) + if listHeader == nil { + // The com.bloks.www.caa.ar.auth_method screen is not always a method + // picker: after a rejected password it can be a single-method + // confirmation dialog (we'll send you a token...). + err := b.CurrentPage. + FindDescendant(FilterByAttribute("bk.data.TextSpan", "text", "Continue")). + FindContainingButton(). + TapButton(ctx, b.CurrentPage.Interpreter) + if err != nil { + return nil, fmt.Errorf("tapping continue on auth method screen: %w", err) + } + break + } + + listItems := listHeader. FindAncestor(FilterByComponent("bk.components.Collection")). FindDescendant(FilterByAttribute("bk.components.BoxDecoration", "border_width", "1dp")). FindAncestor(FilterByComponent("bk.components.Flexbox")).