Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

locator.waitFor errors during a page navigation #1472

Open
2 tasks done
ankur22 opened this issue Oct 8, 2024 · 4 comments
Open
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

@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 #1501 so that we can work on the actual fix for this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants