diff --git a/browser-versions.json b/browser-versions.json index 4e3334648db7..beec05263965 100644 --- a/browser-versions.json +++ b/browser-versions.json @@ -1,4 +1,4 @@ { - "chrome:beta": "98.0.4758.80", + "chrome:beta": "99.0.4844.27", "chrome:stable": "98.0.4758.80" } diff --git a/packages/driver/src/cy/chai/inspect.ts b/packages/driver/src/cy/chai/inspect.ts index 512336709ff4..5dfccd83fdc0 100644 --- a/packages/driver/src/cy/chai/inspect.ts +++ b/packages/driver/src/cy/chai/inspect.ts @@ -54,6 +54,18 @@ export function create (chai) { typeof object.nodeName === 'string' } + // We can't just check if object instanceof ShadowRoot, because it might be the document of an iframe, + // which in Chrome 99+ is a separate class, and instanceof ShadowRoot returns false. + const isShadowRoot = function (object) { + return isDOMElement(object.host) && object.host.shadowRoot === object + } + + // We can't just check if object instanceof Document, because it might be the document of an iframe, + // which in Chrome 99+ is a separate class, and instanceof Document returns false. + const isDocument = function (object) { + return object.defaultView && object.defaultView === object.defaultView.window + } + let formatValueHook const setFormatValueHook = (fn) => formatValueHook = fn @@ -124,6 +136,14 @@ export function create (chai) { } } + if (isShadowRoot(value)) { + return value.innerHTML + } + + if (isDocument(value)) { + return value.documentElement.outerHTML + } + // Look up the keys of the object. let visibleKeys = getEnumerableProperties(value) let keys = ctx.showHidden ? getProperties(value) : visibleKeys diff --git a/packages/driver/src/cypress/stack_utils.ts b/packages/driver/src/cypress/stack_utils.ts index 0a3d2a188d3d..4b9f771e3224 100644 --- a/packages/driver/src/cypress/stack_utils.ts +++ b/packages/driver/src/cypress/stack_utils.ts @@ -139,13 +139,21 @@ const captureUserInvocationStack = (ErrorConstructor, userInvocationStack?) => { if (!userInvocationStack) { const newErr = new ErrorConstructor('userInvocationStack') + userInvocationStack = newErr.stack + // if browser natively supports Error.captureStackTrace, use it (chrome) (must be bound) // otherwise use our polyfill on top.Error const captureStackTrace = ErrorConstructor.captureStackTrace ? ErrorConstructor.captureStackTrace.bind(ErrorConstructor) : Error.captureStackTrace captureStackTrace(newErr, captureUserInvocationStack) - userInvocationStack = newErr.stack + // On Chrome 99+, captureStackTrace strips away the whole stack, + // leaving nothing beyond the error message. If we get back a single line + // (just the error message with no stack trace), then use the original value + // instead of the trimmed one. + if (newErr.stack.match('\n')) { + userInvocationStack = newErr.stack + } } userInvocationStack = normalizedUserInvocationStack(userInvocationStack)