Skip to content
This repository has been archived by the owner on Jan 30, 2025. It is now read-only.

locator.waitFor errors during a page navigation #1472

Closed
2 tasks done
ankur22 opened this issue Oct 8, 2024 · 4 comments
Closed
2 tasks done

locator.waitFor errors during a page navigation #1472

ankur22 opened this issue Oct 8, 2024 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@ankur22
Copy link
Collaborator

ankur22 commented Oct 8, 2024

Brief summary

When working with locator.waitFor, it will error causing the iteration to end early if a navigation occurs while the waitFor is waiting. This happens when we perform something like:

await page.goto('some-url') // Pointing to a URL which perform multiple redirects such as login via SSO

await page.locator('some-selector').waitFor() // This can fail if the navigation is still redirecting/not completed

xk6-browser version

NA

OS

NA

Chrome version

NA

Docker version and image (if applicable)

No response

Steps to reproduce the problem

NA

Expected behaviour

It should wait until the selector is found and not error and end the iteration if a navigation occurs while a waitFor is waiting.

Actual behaviour

It errors with something like Uncaught (in promise) waiting for "//div[text()=\"Sign in\"]": Inspected target navigated or closed

Tasks

Preview Give feedback
@ankur22 ankur22 added the bug Something isn't working label Oct 8, 2024
@ankur22
Copy link
Collaborator Author

ankur22 commented Oct 8, 2024

I believe we need to run waitFor on the global context (i.e. use runtime.Evaluate, instead of runtime.CallFunction), but it's going to be difficult, and i'm not 100% sure since it's not easy to POC.

There is an extremely horrible workaround 😅 Basically retry until it works, here's a POC PR to showcase the (terrible but working) idea.

@inancgumus
Copy link
Member

Retrying sounds fine to me :)

@ankur22
Copy link
Collaborator Author

ankur22 commented Oct 9, 2024

I did get it to run on the global context but that didn't help. The following is a drop in replacement for the existing waitForSelector that is called from waitFor, but it doesn't work:

func (h *ElementHandle) waitForSelector(apiCtx context.Context, selector string, opts *FrameWaitForSelectorOptions) (*ElementHandle, error) {
	parsedSelector, err := NewSelector(selector)
	if err != nil {
		return nil, err
	}

	b, _ := json.Marshal(parsedSelector)
	fmt.Println(string(b))

	fn := fmt.Sprintf(`
	%s

	const is = new InjectedScript();
	return is.waitForSelector(%s, null, true, '%s', 'raf', %d);
	`, injectedScriptSource, string(b), opts.State.String(), opts.Timeout.Milliseconds())

	action := runtime.Evaluate(fn).
		WithAwaitPromise(true)

	result, exceptionDetails, err := action.Do(cdp.WithExecutor(h.ctx, h.session))
	if err != nil {
		return nil, fmt.Errorf("evaluating JS in global context: %w", err)
	}
	if exceptionDetails != nil {
		return nil, fmt.Errorf("%s", parseExceptionDetails(exceptionDetails))
	}

	res := NewJSHandle(h.ctx, h.session, h.execCtx, h.frame, result, h.logger)

	switch r := res.(type) {
	case *ElementHandle:
		return r, nil
	default:
		return nil, nil
	}
}

@ankur22
Copy link
Collaborator Author

ankur22 commented Oct 29, 2024

I've created grafana/k6#4309 so that we can work on the actual fix for this issue.

@ankur22 ankur22 closed this as completed Dec 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants