summaryrefslogtreecommitdiff
path: root/vendor/github.com/playwright-community/playwright-go/browser_context.go
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-12 16:33:27 -0600
committermo khan <mo@mokhan.ca>2025-05-12 16:33:27 -0600
commit29b59441a4bbada64d8d07bd2609f15dfde670e5 (patch)
tree3b3583edb261279cfcdfd9eed904d118c4bf67b1 /vendor/github.com/playwright-community/playwright-go/browser_context.go
parent78ccd9a4312eab7e11da4413733a12953f88a4fe (diff)
test: remove UI tests
Diffstat (limited to 'vendor/github.com/playwright-community/playwright-go/browser_context.go')
-rw-r--r--vendor/github.com/playwright-community/playwright-go/browser_context.go914
1 files changed, 0 insertions, 914 deletions
diff --git a/vendor/github.com/playwright-community/playwright-go/browser_context.go b/vendor/github.com/playwright-community/playwright-go/browser_context.go
deleted file mode 100644
index 1d420d3..0000000
--- a/vendor/github.com/playwright-community/playwright-go/browser_context.go
+++ /dev/null
@@ -1,914 +0,0 @@
-package playwright
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "os"
- "regexp"
- "slices"
- "strings"
- "sync"
-
- "github.com/playwright-community/playwright-go/internal/safe"
-)
-
-type browserContextImpl struct {
- channelOwner
- timeoutSettings *timeoutSettings
- closeWasCalled bool
- options *BrowserNewContextOptions
- pages []Page
- routes []*routeHandlerEntry
- webSocketRoutes []*webSocketRouteHandler
- ownedPage Page
- browser *browserImpl
- serviceWorkers []Worker
- backgroundPages []Page
- bindings *safe.SyncMap[string, BindingCallFunction]
- tracing *tracingImpl
- request *apiRequestContextImpl
- harRecorders map[string]harRecordingMetadata
- closed chan struct{}
- closeReason *string
- harRouters []*harRouter
- clock Clock
-}
-
-func (b *browserContextImpl) Clock() Clock {
- return b.clock
-}
-
-func (b *browserContextImpl) SetDefaultNavigationTimeout(timeout float64) {
- b.setDefaultNavigationTimeoutImpl(&timeout)
-}
-
-func (b *browserContextImpl) setDefaultNavigationTimeoutImpl(timeout *float64) {
- b.timeoutSettings.SetDefaultNavigationTimeout(timeout)
- b.channel.SendNoReplyInternal("setDefaultNavigationTimeoutNoReply", map[string]interface{}{
- "timeout": timeout,
- })
-}
-
-func (b *browserContextImpl) SetDefaultTimeout(timeout float64) {
- b.setDefaultTimeoutImpl(&timeout)
-}
-
-func (b *browserContextImpl) setDefaultTimeoutImpl(timeout *float64) {
- b.timeoutSettings.SetDefaultTimeout(timeout)
- b.channel.SendNoReplyInternal("setDefaultTimeoutNoReply", map[string]interface{}{
- "timeout": timeout,
- })
-}
-
-func (b *browserContextImpl) Pages() []Page {
- b.Lock()
- defer b.Unlock()
- return b.pages
-}
-
-func (b *browserContextImpl) Browser() Browser {
- return b.browser
-}
-
-func (b *browserContextImpl) Tracing() Tracing {
- return b.tracing
-}
-
-func (b *browserContextImpl) NewCDPSession(page interface{}) (CDPSession, error) {
- params := map[string]interface{}{}
-
- if p, ok := page.(*pageImpl); ok {
- params["page"] = p.channel
- } else if f, ok := page.(*frameImpl); ok {
- params["frame"] = f.channel
- } else {
- return nil, fmt.Errorf("not page or frame: %v", page)
- }
-
- channel, err := b.channel.Send("newCDPSession", params)
- if err != nil {
- return nil, err
- }
-
- cdpSession := fromChannel(channel).(*cdpSessionImpl)
-
- return cdpSession, nil
-}
-
-func (b *browserContextImpl) NewPage() (Page, error) {
- if b.ownedPage != nil {
- return nil, errors.New("Please use browser.NewContext()")
- }
- channel, err := b.channel.Send("newPage")
- if err != nil {
- return nil, err
- }
- return fromChannel(channel).(*pageImpl), nil
-}
-
-func (b *browserContextImpl) Cookies(urls ...string) ([]Cookie, error) {
- result, err := b.channel.Send("cookies", map[string]interface{}{
- "urls": urls,
- })
- if err != nil {
- return nil, err
- }
- cookies := make([]Cookie, len(result.([]interface{})))
- for i, item := range result.([]interface{}) {
- cookie := &Cookie{}
- remapMapToStruct(item, cookie)
- cookies[i] = *cookie
- }
- return cookies, nil
-}
-
-func (b *browserContextImpl) AddCookies(cookies []OptionalCookie) error {
- _, err := b.channel.Send("addCookies", map[string]interface{}{
- "cookies": cookies,
- })
- return err
-}
-
-func (b *browserContextImpl) ClearCookies(options ...BrowserContextClearCookiesOptions) error {
- params := map[string]interface{}{}
- if len(options) == 1 {
- if options[0].Domain != nil {
- switch t := options[0].Domain.(type) {
- case string:
- params["domain"] = t
- case *string:
- params["domain"] = t
- case *regexp.Regexp:
- pattern, flag := convertRegexp(t)
- params["domainRegexSource"] = pattern
- params["domainRegexFlags"] = flag
- default:
- return errors.New("invalid type for domain, expected string or *regexp.Regexp")
- }
- }
- if options[0].Name != nil {
- switch t := options[0].Name.(type) {
- case string:
- params["name"] = t
- case *string:
- params["name"] = t
- case *regexp.Regexp:
- pattern, flag := convertRegexp(t)
- params["nameRegexSource"] = pattern
- params["nameRegexFlags"] = flag
- default:
- return errors.New("invalid type for name, expected string or *regexp.Regexp")
- }
- }
- if options[0].Path != nil {
- switch t := options[0].Path.(type) {
- case string:
- params["path"] = t
- case *string:
- params["path"] = t
- case *regexp.Regexp:
- pattern, flag := convertRegexp(t)
- params["pathRegexSource"] = pattern
- params["pathRegexFlags"] = flag
- default:
- return errors.New("invalid type for path, expected string or *regexp.Regexp")
- }
- }
- }
- _, err := b.channel.Send("clearCookies", params)
- return err
-}
-
-func (b *browserContextImpl) GrantPermissions(permissions []string, options ...BrowserContextGrantPermissionsOptions) error {
- _, err := b.channel.Send("grantPermissions", map[string]interface{}{
- "permissions": permissions,
- }, options)
- return err
-}
-
-func (b *browserContextImpl) ClearPermissions() error {
- _, err := b.channel.Send("clearPermissions")
- return err
-}
-
-func (b *browserContextImpl) SetGeolocation(geolocation *Geolocation) error {
- _, err := b.channel.Send("setGeolocation", map[string]interface{}{
- "geolocation": geolocation,
- })
- return err
-}
-
-func (b *browserContextImpl) ResetGeolocation() error {
- _, err := b.channel.Send("setGeolocation", map[string]interface{}{})
- return err
-}
-
-func (b *browserContextImpl) SetExtraHTTPHeaders(headers map[string]string) error {
- _, err := b.channel.Send("setExtraHTTPHeaders", map[string]interface{}{
- "headers": serializeMapToNameAndValue(headers),
- })
- return err
-}
-
-func (b *browserContextImpl) SetOffline(offline bool) error {
- _, err := b.channel.Send("setOffline", map[string]interface{}{
- "offline": offline,
- })
- return err
-}
-
-func (b *browserContextImpl) AddInitScript(script Script) error {
- var source string
- if script.Content != nil {
- source = *script.Content
- }
- if script.Path != nil {
- content, err := os.ReadFile(*script.Path)
- if err != nil {
- return err
- }
- source = string(content)
- }
- _, err := b.channel.Send("addInitScript", map[string]interface{}{
- "source": source,
- })
- return err
-}
-
-func (b *browserContextImpl) ExposeBinding(name string, binding BindingCallFunction, handle ...bool) error {
- needsHandle := false
- if len(handle) == 1 {
- needsHandle = handle[0]
- }
- for _, page := range b.Pages() {
- if _, ok := page.(*pageImpl).bindings.Load(name); ok {
- return fmt.Errorf("Function '%s' has been already registered in one of the pages", name)
- }
- }
- if _, ok := b.bindings.Load(name); ok {
- return fmt.Errorf("Function '%s' has been already registered", name)
- }
- _, err := b.channel.Send("exposeBinding", map[string]interface{}{
- "name": name,
- "needsHandle": needsHandle,
- })
- if err != nil {
- return err
- }
- b.bindings.Store(name, binding)
- return err
-}
-
-func (b *browserContextImpl) ExposeFunction(name string, binding ExposedFunction) error {
- return b.ExposeBinding(name, func(source *BindingSource, args ...interface{}) interface{} {
- return binding(args...)
- })
-}
-
-func (b *browserContextImpl) Route(url interface{}, handler routeHandler, times ...int) error {
- b.Lock()
- defer b.Unlock()
- b.routes = slices.Insert(b.routes, 0, newRouteHandlerEntry(newURLMatcher(url, b.options.BaseURL), handler, times...))
- return b.updateInterceptionPatterns()
-}
-
-func (b *browserContextImpl) Unroute(url interface{}, handlers ...routeHandler) error {
- removed, remaining, err := unroute(b.routes, url, handlers...)
- if err != nil {
- return err
- }
- return b.unrouteInternal(removed, remaining, UnrouteBehaviorDefault)
-}
-
-func (b *browserContextImpl) unrouteInternal(removed []*routeHandlerEntry, remaining []*routeHandlerEntry, behavior *UnrouteBehavior) error {
- b.Lock()
- defer b.Unlock()
- b.routes = remaining
- if err := b.updateInterceptionPatterns(); err != nil {
- return err
- }
- if behavior == nil || behavior == UnrouteBehaviorDefault {
- return nil
- }
- wg := &sync.WaitGroup{}
- for _, entry := range removed {
- wg.Add(1)
- go func(entry *routeHandlerEntry) {
- defer wg.Done()
- entry.Stop(string(*behavior))
- }(entry)
- }
- wg.Wait()
- return nil
-}
-
-func (b *browserContextImpl) UnrouteAll(options ...BrowserContextUnrouteAllOptions) error {
- var behavior *UnrouteBehavior
- if len(options) == 1 {
- behavior = options[0].Behavior
- }
- defer b.disposeHarRouters()
- return b.unrouteInternal(b.routes, []*routeHandlerEntry{}, behavior)
-}
-
-func (b *browserContextImpl) disposeHarRouters() {
- for _, router := range b.harRouters {
- router.dispose()
- }
- b.harRouters = make([]*harRouter, 0)
-}
-
-func (b *browserContextImpl) Request() APIRequestContext {
- return b.request
-}
-
-func (b *browserContextImpl) RouteFromHAR(har string, options ...BrowserContextRouteFromHAROptions) error {
- opt := BrowserContextRouteFromHAROptions{}
- if len(options) == 1 {
- opt = options[0]
- }
- if opt.Update != nil && *opt.Update {
- var updateContent *HarContentPolicy
- switch opt.UpdateContent {
- case RouteFromHarUpdateContentPolicyAttach:
- updateContent = HarContentPolicyAttach
- case RouteFromHarUpdateContentPolicyEmbed:
- updateContent = HarContentPolicyEmbed
- }
- return b.recordIntoHar(har, browserContextRecordIntoHarOptions{
- URL: opt.URL,
- UpdateContent: updateContent,
- UpdateMode: opt.UpdateMode,
- })
- }
- notFound := opt.NotFound
- if notFound == nil {
- notFound = HarNotFoundAbort
- }
- router := newHarRouter(b.connection.localUtils, har, *notFound, opt.URL)
- b.harRouters = append(b.harRouters, router)
- return router.addContextRoute(b)
-}
-
-func (b *browserContextImpl) WaitForEvent(event string, options ...BrowserContextWaitForEventOptions) (interface{}, error) {
- return b.waiterForEvent(event, options...).Wait()
-}
-
-func (b *browserContextImpl) waiterForEvent(event string, options ...BrowserContextWaitForEventOptions) *waiter {
- timeout := b.timeoutSettings.Timeout()
- var predicate interface{} = nil
- if len(options) == 1 {
- if options[0].Timeout != nil {
- timeout = *options[0].Timeout
- }
- predicate = options[0].Predicate
- }
- waiter := newWaiter().WithTimeout(timeout)
- waiter.RejectOnEvent(b, "close", ErrTargetClosed)
- return waiter.WaitForEvent(b, event, predicate)
-}
-
-func (b *browserContextImpl) ExpectConsoleMessage(cb func() error, options ...BrowserContextExpectConsoleMessageOptions) (ConsoleMessage, error) {
- var w *waiter
- if len(options) == 1 {
- w = b.waiterForEvent("console", BrowserContextWaitForEventOptions{
- Predicate: options[0].Predicate,
- Timeout: options[0].Timeout,
- })
- } else {
- w = b.waiterForEvent("console")
- }
- ret, err := w.RunAndWait(cb)
- if err != nil {
- return nil, err
- }
- return ret.(ConsoleMessage), nil
-}
-
-func (b *browserContextImpl) ExpectEvent(event string, cb func() error, options ...BrowserContextExpectEventOptions) (interface{}, error) {
- if len(options) == 1 {
- return b.waiterForEvent(event, BrowserContextWaitForEventOptions(options[0])).RunAndWait(cb)
- }
- return b.waiterForEvent(event).RunAndWait(cb)
-}
-
-func (b *browserContextImpl) ExpectPage(cb func() error, options ...BrowserContextExpectPageOptions) (Page, error) {
- var w *waiter
- if len(options) == 1 {
- w = b.waiterForEvent("page", BrowserContextWaitForEventOptions{
- Predicate: options[0].Predicate,
- Timeout: options[0].Timeout,
- })
- } else {
- w = b.waiterForEvent("page")
- }
- ret, err := w.RunAndWait(cb)
- if err != nil {
- return nil, err
- }
- return ret.(Page), nil
-}
-
-func (b *browserContextImpl) Close(options ...BrowserContextCloseOptions) error {
- if b.closeWasCalled {
- return nil
- }
- if len(options) == 1 {
- b.closeReason = options[0].Reason
- }
- b.closeWasCalled = true
-
- _, err := b.channel.connection.WrapAPICall(func() (interface{}, error) {
- return nil, b.request.Dispose(APIRequestContextDisposeOptions{
- Reason: b.closeReason,
- })
- }, true)
- if err != nil {
- return err
- }
-
- innerClose := func() (interface{}, error) {
- for harId, harMetaData := range b.harRecorders {
- overrides := map[string]interface{}{}
- if harId != "" {
- overrides["harId"] = harId
- }
- response, err := b.channel.Send("harExport", overrides)
- if err != nil {
- return nil, err
- }
- artifact := fromChannel(response).(*artifactImpl)
- // Server side will compress artifact if content is attach or if file is .zip.
- needCompressed := strings.HasSuffix(strings.ToLower(harMetaData.Path), ".zip")
- if !needCompressed && harMetaData.Content == HarContentPolicyAttach {
- tmpPath := harMetaData.Path + ".tmp"
- if err := artifact.SaveAs(tmpPath); err != nil {
- return nil, err
- }
- err = b.connection.localUtils.HarUnzip(tmpPath, harMetaData.Path)
- if err != nil {
- return nil, err
- }
- } else {
- if err := artifact.SaveAs(harMetaData.Path); err != nil {
- return nil, err
- }
- }
- if err := artifact.Delete(); err != nil {
- return nil, err
- }
- }
- return nil, nil
- }
-
- _, err = b.channel.connection.WrapAPICall(innerClose, true)
- if err != nil {
- return err
- }
-
- _, err = b.channel.Send("close", map[string]interface{}{
- "reason": b.closeReason,
- })
- if err != nil {
- return err
- }
- <-b.closed
- return err
-}
-
-type browserContextRecordIntoHarOptions struct {
- Page Page
- URL interface{}
- UpdateContent *HarContentPolicy
- UpdateMode *HarMode
-}
-
-func (b *browserContextImpl) recordIntoHar(har string, options ...browserContextRecordIntoHarOptions) error {
- overrides := map[string]interface{}{}
- harOptions := recordHarInputOptions{
- Path: har,
- Content: HarContentPolicyAttach,
- Mode: HarModeMinimal,
- }
- if len(options) == 1 {
- if options[0].UpdateContent != nil {
- harOptions.Content = options[0].UpdateContent
- }
- if options[0].UpdateMode != nil {
- harOptions.Mode = options[0].UpdateMode
- }
- harOptions.URL = options[0].URL
- overrides["options"] = prepareRecordHarOptions(harOptions)
- if options[0].Page != nil {
- overrides["page"] = options[0].Page.(*pageImpl).channel
- }
- }
- harId, err := b.channel.Send("harStart", overrides)
- if err != nil {
- return err
- }
- b.harRecorders[harId.(string)] = harRecordingMetadata{
- Path: har,
- Content: harOptions.Content,
- }
- return nil
-}
-
-func (b *browserContextImpl) StorageState(paths ...string) (*StorageState, error) {
- result, err := b.channel.SendReturnAsDict("storageState")
- if err != nil {
- return nil, err
- }
- if len(paths) == 1 {
- file, err := os.Create(paths[0])
- if err != nil {
- return nil, err
- }
- if err := json.NewEncoder(file).Encode(result); err != nil {
- return nil, err
- }
- if err := file.Close(); err != nil {
- return nil, err
- }
- }
- var storageState StorageState
- remapMapToStruct(result, &storageState)
- return &storageState, nil
-}
-
-func (b *browserContextImpl) onBinding(binding *bindingCallImpl) {
- function, ok := b.bindings.Load(binding.initializer["name"].(string))
- if !ok || function == nil {
- return
- }
- go binding.Call(function)
-}
-
-func (b *browserContextImpl) onClose() {
- if b.browser != nil {
- contexts := make([]BrowserContext, 0)
- b.browser.Lock()
- for _, context := range b.browser.contexts {
- if context != b {
- contexts = append(contexts, context)
- }
- }
- b.browser.contexts = contexts
- b.browser.Unlock()
- }
- b.disposeHarRouters()
- b.Emit("close", b)
-}
-
-func (b *browserContextImpl) onPage(page Page) {
- b.Lock()
- b.pages = append(b.pages, page)
- b.Unlock()
- b.Emit("page", page)
- opener, _ := page.Opener()
- if opener != nil && !opener.IsClosed() {
- opener.Emit("popup", page)
- }
-}
-
-func (b *browserContextImpl) onRoute(route *routeImpl) {
- b.Lock()
- route.context = b
- page := route.Request().(*requestImpl).safePage()
- routes := make([]*routeHandlerEntry, len(b.routes))
- copy(routes, b.routes)
- b.Unlock()
-
- checkInterceptionIfNeeded := func() {
- b.Lock()
- defer b.Unlock()
- if len(b.routes) == 0 {
- _, err := b.connection.WrapAPICall(func() (interface{}, error) {
- err := b.updateInterceptionPatterns()
- return nil, err
- }, true)
- if err != nil {
- logger.Error("could not update interception patterns", "error", err)
- }
- }
- }
-
- url := route.Request().URL()
- for _, handlerEntry := range routes {
- // If the page or the context was closed we stall all requests right away.
- if (page != nil && page.closeWasCalled) || b.closeWasCalled {
- return
- }
- if !handlerEntry.Matches(url) {
- continue
- }
- if !slices.ContainsFunc(b.routes, func(entry *routeHandlerEntry) bool {
- return entry == handlerEntry
- }) {
- continue
- }
- if handlerEntry.WillExceed() {
- b.routes = slices.DeleteFunc(b.routes, func(rhe *routeHandlerEntry) bool {
- return rhe == handlerEntry
- })
- }
- handled := handlerEntry.Handle(route)
- checkInterceptionIfNeeded()
- yes := <-handled
- if yes {
- return
- }
- }
- // If the page is closed or unrouteAll() was called without waiting and interception disabled,
- // the method will throw an error - silence it.
- _ = route.internalContinue(true)
-}
-
-func (b *browserContextImpl) updateInterceptionPatterns() error {
- patterns := prepareInterceptionPatterns(b.routes)
- _, err := b.channel.Send("setNetworkInterceptionPatterns", map[string]interface{}{
- "patterns": patterns,
- })
- return err
-}
-
-func (b *browserContextImpl) pause() <-chan error {
- ret := make(chan error, 1)
- go func() {
- _, err := b.channel.Send("pause")
- ret <- err
- }()
- return ret
-}
-
-func (b *browserContextImpl) onBackgroundPage(ev map[string]interface{}) {
- b.Lock()
- p := fromChannel(ev["page"]).(*pageImpl)
- p.browserContext = b
- b.backgroundPages = append(b.backgroundPages, p)
- b.Unlock()
- b.Emit("backgroundpage", p)
-}
-
-func (b *browserContextImpl) onServiceWorker(worker *workerImpl) {
- worker.context = b
- b.serviceWorkers = append(b.serviceWorkers, worker)
- b.Emit("serviceworker", worker)
-}
-
-func (b *browserContextImpl) setOptions(options *BrowserNewContextOptions, tracesDir *string) {
- if options == nil {
- options = &BrowserNewContextOptions{}
- }
- b.options = options
- if b.options != nil && b.options.RecordHarPath != nil {
- b.harRecorders[""] = harRecordingMetadata{
- Path: *b.options.RecordHarPath,
- Content: b.options.RecordHarContent,
- }
- }
- if tracesDir != nil {
- b.tracing.tracesDir = *tracesDir
- }
-}
-
-func (b *browserContextImpl) BackgroundPages() []Page {
- b.Lock()
- defer b.Unlock()
- return b.backgroundPages
-}
-
-func (b *browserContextImpl) ServiceWorkers() []Worker {
- b.Lock()
- defer b.Unlock()
- return b.serviceWorkers
-}
-
-func (b *browserContextImpl) OnBackgroundPage(fn func(Page)) {
- b.On("backgroundpage", fn)
-}
-
-func (b *browserContextImpl) OnClose(fn func(BrowserContext)) {
- b.On("close", fn)
-}
-
-func (b *browserContextImpl) OnConsole(fn func(ConsoleMessage)) {
- b.On("console", fn)
-}
-
-func (b *browserContextImpl) OnDialog(fn func(Dialog)) {
- b.On("dialog", fn)
-}
-
-func (b *browserContextImpl) OnPage(fn func(Page)) {
- b.On("page", fn)
-}
-
-func (b *browserContextImpl) OnRequest(fn func(Request)) {
- b.On("request", fn)
-}
-
-func (b *browserContextImpl) OnRequestFailed(fn func(Request)) {
- b.On("requestfailed", fn)
-}
-
-func (b *browserContextImpl) OnRequestFinished(fn func(Request)) {
- b.On("requestfinished", fn)
-}
-
-func (b *browserContextImpl) OnResponse(fn func(Response)) {
- b.On("response", fn)
-}
-
-func (b *browserContextImpl) OnWebError(fn func(WebError)) {
- b.On("weberror", fn)
-}
-
-func (b *browserContextImpl) RouteWebSocket(url interface{}, handler func(WebSocketRoute)) error {
- b.Lock()
- defer b.Unlock()
- b.webSocketRoutes = slices.Insert(b.webSocketRoutes, 0, newWebSocketRouteHandler(newURLMatcher(url, b.options.BaseURL), handler))
-
- return b.updateWebSocketInterceptionPatterns()
-}
-
-func (b *browserContextImpl) onWebSocketRoute(wr WebSocketRoute) {
- b.Lock()
- index := slices.IndexFunc(b.webSocketRoutes, func(r *webSocketRouteHandler) bool {
- return r.Matches(wr.URL())
- })
- if index == -1 {
- b.Unlock()
- _, err := wr.ConnectToServer()
- if err != nil {
- logger.Error("could not connect to WebSocket server", "error", err)
- }
- return
- }
- handler := b.webSocketRoutes[index]
- b.Unlock()
- handler.Handle(wr)
-}
-
-func (b *browserContextImpl) updateWebSocketInterceptionPatterns() error {
- patterns := prepareWebSocketRouteHandlerInterceptionPatterns(b.webSocketRoutes)
- _, err := b.channel.Send("setWebSocketInterceptionPatterns", map[string]interface{}{
- "patterns": patterns,
- })
- return err
-}
-
-func (b *browserContextImpl) effectiveCloseReason() *string {
- b.Lock()
- defer b.Unlock()
- if b.closeReason != nil {
- return b.closeReason
- }
- if b.browser != nil {
- return b.browser.closeReason
- }
- return nil
-}
-
-func newBrowserContext(parent *channelOwner, objectType string, guid string, initializer map[string]interface{}) *browserContextImpl {
- bt := &browserContextImpl{
- timeoutSettings: newTimeoutSettings(nil),
- pages: make([]Page, 0),
- backgroundPages: make([]Page, 0),
- routes: make([]*routeHandlerEntry, 0),
- bindings: safe.NewSyncMap[string, BindingCallFunction](),
- harRecorders: make(map[string]harRecordingMetadata),
- closed: make(chan struct{}, 1),
- harRouters: make([]*harRouter, 0),
- }
- bt.createChannelOwner(bt, parent, objectType, guid, initializer)
- if parent.objectType == "Browser" {
- bt.browser = fromChannel(parent.channel).(*browserImpl)
- bt.browser.contexts = append(bt.browser.contexts, bt)
- }
- bt.tracing = fromChannel(initializer["tracing"]).(*tracingImpl)
- bt.request = fromChannel(initializer["requestContext"]).(*apiRequestContextImpl)
- bt.clock = newClock(bt)
- bt.channel.On("bindingCall", func(params map[string]interface{}) {
- bt.onBinding(fromChannel(params["binding"]).(*bindingCallImpl))
- })
-
- bt.channel.On("close", bt.onClose)
- bt.channel.On("page", func(payload map[string]interface{}) {
- bt.onPage(fromChannel(payload["page"]).(*pageImpl))
- })
- bt.channel.On("route", func(params map[string]interface{}) {
- bt.channel.CreateTask(func() {
- bt.onRoute(fromChannel(params["route"]).(*routeImpl))
- })
- })
- bt.channel.On("webSocketRoute", func(params map[string]interface{}) {
- bt.channel.CreateTask(func() {
- bt.onWebSocketRoute(fromChannel(params["webSocketRoute"]).(*webSocketRouteImpl))
- })
- })
- bt.channel.On("backgroundPage", bt.onBackgroundPage)
- bt.channel.On("serviceWorker", func(params map[string]interface{}) {
- bt.onServiceWorker(fromChannel(params["worker"]).(*workerImpl))
- })
- bt.channel.On("console", func(ev map[string]interface{}) {
- message := newConsoleMessage(ev)
- bt.Emit("console", message)
- if message.page != nil {
- message.page.Emit("console", message)
- }
- })
- bt.channel.On("dialog", func(params map[string]interface{}) {
- dialog := fromChannel(params["dialog"]).(*dialogImpl)
- go func() {
- hasListeners := bt.Emit("dialog", dialog)
- page := dialog.page
- if page != nil {
- if page.Emit("dialog", dialog) {
- hasListeners = true
- }
- }
- if !hasListeners {
- // Although we do similar handling on the server side, we still need this logic
- // on the client side due to a possible race condition between two async calls:
- // a) removing "dialog" listener subscription (client->server)
- // b) actual "dialog" event (server->client)
- if dialog.Type() == "beforeunload" {
- _ = dialog.Accept()
- } else {
- _ = dialog.Dismiss()
- }
- }
- }()
- })
- bt.channel.On(
- "pageError", func(ev map[string]interface{}) {
- pwErr := &Error{}
- remapMapToStruct(ev["error"].(map[string]interface{})["error"], pwErr)
- err := parseError(*pwErr)
- page := fromNullableChannel(ev["page"])
- if page != nil {
- bt.Emit("weberror", newWebError(page.(*pageImpl), err))
- page.(*pageImpl).Emit("pageerror", err)
- } else {
- bt.Emit("weberror", newWebError(nil, err))
- }
- },
- )
- bt.channel.On("request", func(ev map[string]interface{}) {
- request := fromChannel(ev["request"]).(*requestImpl)
- page := fromNullableChannel(ev["page"])
- bt.Emit("request", request)
- if page != nil {
- page.(*pageImpl).Emit("request", request)
- }
- })
- bt.channel.On("requestFailed", func(ev map[string]interface{}) {
- request := fromChannel(ev["request"]).(*requestImpl)
- failureText := ev["failureText"]
- if failureText != nil {
- request.failureText = failureText.(string)
- }
- page := fromNullableChannel(ev["page"])
- request.setResponseEndTiming(ev["responseEndTiming"].(float64))
- bt.Emit("requestfailed", request)
- if page != nil {
- page.(*pageImpl).Emit("requestfailed", request)
- }
- })
-
- bt.channel.On("requestFinished", func(ev map[string]interface{}) {
- request := fromChannel(ev["request"]).(*requestImpl)
- response := fromNullableChannel(ev["response"])
- page := fromNullableChannel(ev["page"])
- request.setResponseEndTiming(ev["responseEndTiming"].(float64))
- bt.Emit("requestfinished", request)
- if page != nil {
- page.(*pageImpl).Emit("requestfinished", request)
- }
- if response != nil {
- close(response.(*responseImpl).finished)
- }
- })
- bt.channel.On("response", func(ev map[string]interface{}) {
- response := fromChannel(ev["response"]).(*responseImpl)
- page := fromNullableChannel(ev["page"])
- bt.Emit("response", response)
- if page != nil {
- page.(*pageImpl).Emit("response", response)
- }
- })
- bt.Once("close", func() {
- bt.closed <- struct{}{}
- })
- bt.setEventSubscriptionMapping(map[string]string{
- "console": "console",
- "dialog": "dialog",
- "request": "request",
- "response": "response",
- "requestfinished": "requestFinished",
- "responsefailed": "responseFailed",
- })
- return bt
-}