Repository: fabricjs/fabric.js (ts)

Issue:
[Bug]: Cloning a shape with shadow throws an error.
### CheckList

- [X] I agree to follow this project's Code of Conduct
- [X] I have read and followed the [Contributing Guide](https://github.com/fabricjs/fabric.js/blob/master/CONTRIBUTING.md)
- [X] I have read and followed the [Issue Tracker Guide](https://github.com/fabricjs/fabric.js/blob/master/CONTRIBUTING.md#%EF%B8%8F-issue-tracker)
- [X] I have searched and referenced existing issues and discussions
- [X] I am filing a **BUG** report.
- [X] I have managed to reproduce the bug **after** upgrading to the **latest** version
- [X] I have created an accurate and minimal reproduction

### Version

6.0.0-beta19

### In What environments are you experiencing the problem?

_No response_

### Node Version (if applicable)

None

### Link To Reproduction

https://codesandbox.io/p/devbox/fabric-clone-shadow-pps7l7?file=%2Fsrc%2Ftest-shadow-clone.tsx

### Steps To Reproduce

1. Create a rectangle A with shadow.
2. Call the clone method A.clone for B.
3. It throws an error.


### Expected Behavior

success

### Actual Behavior

<img width="1184" alt="image" src="https://github.com/fabricjs/fabric.js/assets/11306583/2e4008ba-a0cf-460c-8e54-1ac78b3eb6c8">

[demo](https://codesandbox.io/p/devbox/fabric-clone-shadow-pps7l7?file=%2Fsrc%2Ftest-shadow-clone.tsx)

I found that it went to `[Shadow].fromObject().then` . Its return value is not a Promise.

### Error Message & Stack Trace

_No response_

Pull request description:
fix(shadow): Cloning a shape with shadow
When cloning a shadow we expect the fromObject method to return a promise.
In this case it isn't and when a clone operation with a shadow is involved we have an error.

Adding async in front of the fromObject function fixes the problem

close #9711 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b4d64db30..405455c8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## [next]
 
+- fix(Shadow): Cloning a shape with shadow throws an error[#9711](https://github.com/fabricjs/fabric.js/issues/9711)
 - chore(TS): use consistent and improved types for getDefaults and ownDefaults [#9698](https://github.com/fabricjs/fabric.js/pull/9698)
 - fix(SVGParser): Don't crash on nested CSS at-rules [#9707](https://github.com/fabricjs/fabric.js/pull/9707)
 - perf(): measuring canvas size [#9697](https://github.com/fabricjs/fabric.js/pull/9697)
diff --git a/src/Shadow.spec.ts b/src/Shadow.spec.ts
new file mode 100644
index 000000000..0178dd999
--- /dev/null
+++ b/src/Shadow.spec.ts
@@ -0,0 +1,15 @@
+import '../jest.extend';
+import { Shadow } from './Shadow';
+
+describe('Shadow', () => {
+  it('fromObject', async () => {
+    const shadow = await Shadow.fromObject({ color: 'red', offsetX: 10 });
+    expect(shadow).toMatchObjectSnapshot();
+    expect(shadow).toMatchObjectSnapshot({ includeDefaultValues: false });
+  });
+
+  it('fromObject is a promise', async () => {
+    const promise = Shadow.fromObject({});
+    expect(promise.then).toBeDefined();
+  });
+});
diff --git a/src/Shadow.ts b/src/Shadow.ts
index 29316d2ad..f4f97ac98 100644
--- a/src/Shadow.ts
+++ b/src/Shadow.ts
@@ -241,7 +241,7 @@ export class Shadow {
       : data;
   }
 
-  static fromObject(options: Partial<TClassProperties<Shadow>>) {
+  static async fromObject(options: Partial<TClassProperties<Shadow>>) {
     return new this(options);
   }
 }
diff --git a/src/__snapshots__/Shadow.spec.ts.snap b/src/__snapshots__/Shadow.spec.ts.snap
new file mode 100644
index 000000000..6a02e6290
--- /dev/null
+++ b/src/__snapshots__/Shadow.spec.ts.snap
@@ -0,0 +1,27 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Shadow fromObject 1`] = `
+{
+  "affectStroke": false,
+  "blur": 0,
+  "color": "red",
+  "id": 0,
+  "includeDefaultValues": true,
+  "nonScaling": false,
+  "offsetX": 10,
+  "offsetY": 0,
+}
+`;
+
+exports[`Shadow fromObject 2`] = `
+{
+  "affectStroke": false,
+  "blur": 0,
+  "color": "red",
+  "id": 0,
+  "includeDefaultValues": true,
+  "nonScaling": false,
+  "offsetX": 10,
+  "offsetY": 0,
+}
+`;


Test patch:
diff --git a/test/unit/shadow.js b/test/unit/shadow.js
index 214cc5de9..929bee7a7 100644
--- a/test/unit/shadow.js
+++ b/test/unit/shadow.js
@@ -187,8 +187,11 @@
   });
 
   QUnit.test('fromObject', assert => {
-    const shadow = fabric.Shadow.fromObject({ color: 'red', offsetX: 15 });
-    assert.ok(shadow instanceof fabric.Shadow);
+    const done = assert.async();
+    return fabric.Shadow.fromObject({ color: 'red', offsetX: 15 }).then((shadow) => {
+      assert.ok(shadow instanceof fabric.Shadow);
+      done();
+    });
   });
 
   QUnit.test('toSVG', function(assert) {