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

Calling util.inspect throws TypeError: element.getAttributeNames is not a function #1680

Open
DiogoDoreto opened this issue Mar 11, 2025 · 3 comments

Comments

@DiogoDoreto
Copy link

I found some incompatibility between chai, jsdom & iframes. This is a simple way to reproduce the issue:

/**
 * @vitest-environment jsdom
 */

import { test, expect, vi } from 'vitest'
import { util } from 'chai';

test('This fails', () => {
  const frame = document.createElement('iframe');
  document.body.appendChild(frame);
  frame.contentDocument.open();
  frame.contentDocument.write('<div>test</div>');
  frame.contentDocument.close();
  const div = frame.contentDocument.body.querySelector('div');

  expect(() => {
    util.inspect(div.childNodes[0]);
  }).not.toThrow();
});

test('This passes', () => {
  document.body.innerHTML = '<div>test</div>';
  const div = document.body.querySelector('div');
  expect(() => {
    util.inspect(div.childNodes[0])
  }).not.toThrow();
});

Error: TypeError: element.getAttributeNames is not a function

Package versions:

chai: 5.2.0
loupe: 3.1.3
jsdom: 26.0.0
@DiogoDoreto
Copy link
Author

I did the tracing of some of the inner kinds of inspect calls from loupe and identified the problem.

Tracing for the passing test
inspect(value=[object Text])
inspectObject
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=0)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Object)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=0)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Object)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=0)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Object)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=0)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Object)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=0)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Object)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Null])
baseTypesMap[null](value=[object Null])
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Document])
inspectObject
inspectProperty(key=location)
inspect(value=[object Location])
inspectObject
inspectProperty(key=assign)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=_relevantDocument)
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Location])
inspectObject
inspectProperty(key=defaultView)
inspect(value=[object global])
inspectObject
inspectProperty(key=Object)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(Symbol.toStringTag))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object String])
baseTypesMap[string](value=[object String])
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object HTMLHtmlElement])
inspectHTML(element=[object HTMLHtmlElement])
inspectHTML(element=[object HTMLHeadElement])
inspectHTML(element=[object HTMLBodyElement])
inspectHTML(element=[object HTMLDivElement])
inspectHTML(element=[object HTMLIFrameElement])
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object HTMLBodyElement])
inspectHTML(element=[object HTMLBodyElement])
inspectHTML(element=[object HTMLDivElement])
inspectHTML(element=[object HTMLIFrameElement])
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object HTMLDivElement])
inspectHTML(element=[object HTMLDivElement])
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Text])
inspectObject
Tracing for the failing test
inspect(value=[object Text])
inspectObject
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Object])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=_globalObject)
inspect(value=[object Window])
inspectObject
inspectProperty(key=Symbol([webidl2js] constructor registry))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=%Object.prototype%)
inspect(value=[object Object])
inspectObject
inspectProperty(key=constructor)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(DOM SymbolTree))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=parent)
inspect(value=[object Null])
baseTypesMap[null](value=[object Null])
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Document])
inspectObject
inspectProperty(key=location)
inspect(value=[object Location])
inspectObject
inspectProperty(key=assign)
inspect(value=[object Function])
baseTypesMap[function](value=[object Function])
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=_relevantDocument)
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Location])
inspectObject
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object HTMLHtmlElement])
inspectObject
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object HTMLBodyElement])
inspectObject
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(wrapper))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object HTMLDivElement])
inspectObject
inspectProperty(key=Symbol(impl))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=Symbol(SameObject caches))
inspect(value=[object Symbol])
baseTypesMap[symbol](value=[object Symbol])
inspect(value=[object Object])
inspectObject
inspectProperty(key=childNodes)
inspect(value=[object NodeList])
baseTypesMap[NodeList](value=[object NodeList])
inspectHTML(element=[object Text])

Looking at the trace from the bottom, we notice that the inspect(value=[object HTMLDivElement]) is not being recognized as an HTML element due to this line: https://github.com/chaijs/loupe/blob/6531c62f4503b01c6911f765ff4cb67efd98722f/src/index.ts#L155
Because by rendering inside an iframe, the div is an instance of a different HTMLElement object.

@43081j
Copy link
Contributor

43081j commented Mar 12, 2025

Yup cross realm stuff causes this

We have to decide if to support it or not. We do support regexes cross realm so maybe it makes sense to do the same here. Just means slightly more complex code

@DiogoDoreto
Copy link
Author

DiogoDoreto commented Mar 12, 2025

Hi @43081j thanks, for reaching out... I just found a simple change that at least prevents the error from being thrown. I'm preparing a PR for loupe right now

DiogoDoreto added a commit to DiogoDoreto/loupe that referenced this issue Mar 12, 2025
An `HTMLCollection` assumes all items are `Element`s, a `NodeList` however may
also include `Node`s such as `Text` and `Comment`, which does not include the
`getAttributeNames` method.

fixes chaijs/chai#1680
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants