Repository: capricorn86/happy-dom (TypeScript)

Issue:
Vue style binding errors with 15.x (Symbol properties)
**Describe the bug**

With 15.x, attempting to use with Vue and a `v-bind:style` on certain elements (maybe others properties?) results in the following error:

```
 FAIL  test/example-breakage/example.test.ts [ test/example-breakage/example.test.ts ]
TypeError: Cannot convert a Symbol value to a number
 ❯ Object.has node_modules/happy-dom/src/nodes/html-select-element/HTMLSelectElement.ts:123:16
 ❯ patchStyle node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.js:460:28
 ❯ patchProp node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.js:677:5
 ❯ mountElement node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4507:11
 ❯ processElement node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4454:7
 ❯ patch node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4322:11
 ❯ ReactiveEffect.componentUpdateFn [as fn] node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4949:11
 ❯ ReactiveEffect.run node_modules/@vue/reactivity/dist/reactivity.cjs.js:181:19
 ❯ instance.update node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5073:16
```

I dug into this a little bit, and it seems to choke on the `_vod` property, which is a Symbol: https://github.com/vuejs/core/blob/d298c431cc422b53cf4e9c69bf1daf926c33b6e0/packages/runtime-dom/src/directives/vShow.ts#L3

**To Reproduce**

- https://stackblitz.com/edit/vitejs-vite-tphxaf?file=tests%2Fexample.vue&file=tests%2Fexample.test.ts&view=editor
- run `npm run test`
- observe the error
- You'll find a minimal reproduction in the `tests` folder, with a simple `example.vue` and `example.test.ts` file, but I've listed them below for reference too:

<details>
<summary>`example.vue`</summary>

```vue
<template>
  <select
    id="example"
    v-bind:style="{
      '--dropdown-icon': 'some-string',
    }"
  >
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
  </select>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const show = ref(false);
</script>

```

</details>

<details>
<summary>`example.test.ts`</summary>

```ts
import { mount } from '@vue/test-utils';
import { expect, it } from 'vitest';

import example from './example.vue';
const wrapper = mount(example);

it('example', () => {
  expect(true).toBe(true);
});

```

</details>

**Expected behavior**

In 14.x, this worked without issue and allowed tests to run.

**Device:**
 - OS: Windows 11
 - Node.js: 20.17.0
 - happy-dom: 15.7.2
 	- last known working version: 14.12.3




Discussion:

Patch:
diff --git a/packages/happy-dom/src/nodes/html-select-element/HTMLSelectElement.ts b/packages/happy-dom/src/nodes/html-select-element/HTMLSelectElement.ts
index a11538fae..adfa57dee 100644
--- a/packages/happy-dom/src/nodes/html-select-element/HTMLSelectElement.ts
+++ b/packages/happy-dom/src/nodes/html-select-element/HTMLSelectElement.ts
@@ -118,6 +118,10 @@ export default class HTMLSelectElement extends HTMLElement {
 					return true;
 				}
 
+				if (typeof property === 'symbol') {
+					return false;
+				}
+
 				const index = Number(property);
 
 				if (!isNaN(index)) {


Test patch:
diff --git a/packages/happy-dom/test/nodes/html-select-element/HTMLSelectElement.test.ts b/packages/happy-dom/test/nodes/html-select-element/HTMLSelectElement.test.ts
index af6631933..56bcd7e08 100644
--- a/packages/happy-dom/test/nodes/html-select-element/HTMLSelectElement.test.ts
+++ b/packages/happy-dom/test/nodes/html-select-element/HTMLSelectElement.test.ts
@@ -239,6 +239,23 @@ describe('HTMLSelectElement', () => {
 		});
 	});
 
+	describe('get symbol()', () => {
+		it('returns existing symbol properties', () => {
+			const symbol = Symbol('test');
+			element[symbol] = 'test';
+			expect(element[symbol]).toBe('test');
+		});
+
+		it('ignores missing symbol properties', () => {
+			const symbol = Symbol('other-test');
+
+			expect(element[symbol]).toBe(undefined);
+
+			// https://github.com/capricorn86/happy-dom/issues/1526
+			expect(symbol in element).toBe(false);
+		});
+	});
+
 	describe(`set selectedIndex()`, () => {
 		it('Allows -1', () => {
 			element.selectedIndex = -1;