Compare commits
47 Commits
derive-doc
...
franknoiro
Author | SHA1 | Date | |
---|---|---|---|
6fc81cd433 | |||
3dfc2c86e1 | |||
71647ede29 | |||
cd679f4be3 | |||
18d87b99bd | |||
70a2202877 | |||
f5c9f84ae9 | |||
71f701dec7 | |||
bffbed1d42 | |||
9f60ed8e75 | |||
6fa12e70a4 | |||
57b366b2d0 | |||
6f3f5dbda9 | |||
4ed0f08c69 | |||
f6e437793f | |||
31f2332c72 | |||
8dd25715fb | |||
af1f15a7f7 | |||
cb285141d5 | |||
3e7036898f | |||
834f7133d8 | |||
8c5662e458 | |||
f37fc357af | |||
e27e9ecc63 | |||
78b42ea191 | |||
5d02a27122 | |||
49d52ce94b | |||
a572d7b0db | |||
1f405b9327 | |||
0874891dd0 | |||
59d0e079a1 | |||
b9862baed0 | |||
592c5259c6 | |||
950f5cebfd | |||
4c0ea136e0 | |||
81c0035adc | |||
c68e5d7774 | |||
ed8a0e4aaa | |||
322f398049 | |||
bc4d254297 | |||
10b7a772bf | |||
980c139060 | |||
4ee1c96e78 | |||
5e89683801 | |||
e2dd6e742a | |||
b3acb348d9 | |||
0aed462360 |
@ -17,7 +17,7 @@ lastSegX(sketch: Sketch) -> number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | The sketch whose line segment is being queried | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ lastSegY(sketch: Sketch) -> number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | The sketch whose line segment is being queried | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -57,3 +57,55 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
|
|||||||
```
|
```
|
||||||
import increment as inc, decrement as dec from "util.kcl"
|
import increment as inc, decrement as dec from "util.kcl"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Importing files from other CAD systems
|
||||||
|
|
||||||
|
`import` can also be used to import files from other CAD systems. The format of the statement is the
|
||||||
|
same as for KCL files. You can only import the whole file, not items from it. E.g.,
|
||||||
|
|
||||||
|
```
|
||||||
|
import "tests/inputs/cube.obj"
|
||||||
|
|
||||||
|
// Use `cube` just like a KCL object.
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
import "tests/inputs/cube-2.sldprt" as cube
|
||||||
|
|
||||||
|
// Use `cube` just like a KCL object.
|
||||||
|
```
|
||||||
|
|
||||||
|
You can make the file format explicit using a format attribute (useful if using a different
|
||||||
|
extension), e.g.,
|
||||||
|
|
||||||
|
```
|
||||||
|
@(format = obj)
|
||||||
|
import "tests/inputs/cube"
|
||||||
|
```
|
||||||
|
|
||||||
|
For formats lacking unit data (such as STL, OBJ, or PLY files), the default
|
||||||
|
unit of measurement is millimeters. Alternatively you may specify the unit
|
||||||
|
by using an attirbute. Likewise, you can also specify a coordinate system. E.g.,
|
||||||
|
|
||||||
|
```
|
||||||
|
@(unitLength = ft, coords = opengl)
|
||||||
|
import "tests/inputs/cube.obj"
|
||||||
|
```
|
||||||
|
|
||||||
|
When importing a GLTF file, the bin file will be imported as well.
|
||||||
|
|
||||||
|
Import paths are relative to the current project directory. Imports currently only work when
|
||||||
|
using the native Modeling App, not in the browser.
|
||||||
|
|
||||||
|
### Supported values
|
||||||
|
|
||||||
|
File formats: `fbx`, `gltf`/`glb`, `obj`+, `ply`+, `sldprt`, `step`/`stp`, `stl`+. (Those marked with a
|
||||||
|
'+' support customising the length unit and coordinate system).
|
||||||
|
|
||||||
|
Length units: `mm` (the default), `cm`, `m`, `inch`, `ft`, `yd`.
|
||||||
|
|
||||||
|
Coordinate systems:
|
||||||
|
|
||||||
|
- `zoo` (the default), forward: -Y, up: +Z, handedness: right
|
||||||
|
- `opengl`, forward: +Z, up: +Y, handedness: right
|
||||||
|
- `vulkan`, forward: +Z, up: -Y, handedness: left
|
||||||
|
@ -9,7 +9,7 @@ Repeat a 2-dimensional sketch some number of times along a partial or
|
|||||||
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
|
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch]
|
patternCircular2d(sketch_set: SketchSet, instances: integer, center: [number], arc_degrees: number, rotate_duplicates: bool, use_original?: bool) -> [Sketch]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,8 +17,12 @@ patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `data` | [`CircularPattern2dData`](/docs/kcl/types/CircularPattern2dData) | Data for a circular pattern on a 2D sketch. | Yes |
|
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | Which sketch(es) to pattern | Yes |
|
||||||
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
|
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
||||||
|
| `center` | `[number]` | The center about which to make the pattern. This is a 2D vector. | Yes |
|
||||||
|
| `arc_degrees` | `number` | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes |
|
||||||
|
| `rotate_duplicates` | `bool` | Whether or not to rotate the duplicates as they are copied. | Yes |
|
||||||
|
| `use_original` | `bool` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
@ -34,12 +38,12 @@ exampleSketch = startSketchOn('XZ')
|
|||||||
|> line(end = [-1, 0])
|
|> line(end = [-1, 0])
|
||||||
|> line(end = [0, -5])
|
|> line(end = [0, -5])
|
||||||
|> close()
|
|> close()
|
||||||
|> patternCircular2d({
|
|> patternCircular2d(
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
instances = 13,
|
instances = 13,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360,
|
||||||
rotateDuplicates = true
|
rotateDuplicates = true,
|
||||||
}, %)
|
)
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 1)
|
example = extrude(exampleSketch, length = 1)
|
||||||
```
|
```
|
||||||
|
@ -17,7 +17,7 @@ segEnd(tag: TagIdentifier) -> [number]
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ segEndX(tag: TagIdentifier) -> number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ segStartX(tag: TagIdentifier) -> number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ segStartY(tag: TagIdentifier) -> number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
62154
docs/kcl/std.json
16
docs/kcl/types/EnvironmentRef.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
title: "EnvironmentRef"
|
||||||
|
excerpt: ""
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
[`SnapshotRef`](/docs/kcl/types/SnapshotRef)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -19,8 +19,8 @@ A face.
|
|||||||
| `id` |`string`| The id of the face. | No |
|
| `id` |`string`| The id of the face. | No |
|
||||||
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
||||||
| `value` |`string`| The tag of the face. | No |
|
| `value` |`string`| The tag of the face. | No |
|
||||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s X axis be? | No |
|
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No |
|
||||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s Y axis be? | No |
|
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
|
||||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||||
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
||||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A face. | No |
|
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A face. | No |
|
||||||
|
@ -59,23 +59,7 @@ Any KCL value.
|
|||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `type` |enum: `Number`| | No |
|
| `type` |enum: `Number`| | No |
|
||||||
| `value` |`number`| | No |
|
| `value` |`number`| | No |
|
||||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
| `ty` |[`NumericType`](/docs/kcl/types/NumericType)| Any KCL value. | No |
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
**Type:** `object`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
| Property | Type | Description | Required |
|
|
||||||
|----------|------|-------------|----------|
|
|
||||||
| `type` |enum: `Int`| | No |
|
|
||||||
| `value` |`integer`| | No |
|
|
||||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +295,7 @@ Data for an imported geometry.
|
|||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `type` |enum: `Function`| | No |
|
| `type` |enum: `Function`| | No |
|
||||||
| `memory` |[`ProgramMemory`](/docs/kcl/types/ProgramMemory)| Any KCL value. | No |
|
| `memory` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| Any KCL value. | No |
|
||||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||||
|
|
||||||
|
|
||||||
@ -351,6 +335,23 @@ Data for an imported geometry.
|
|||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Tombstone`| | No |
|
||||||
|
| `value` |`null`| | No |
|
||||||
|
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
250
docs/kcl/types/NumericType.md
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
---
|
||||||
|
title: "NumericType"
|
||||||
|
excerpt: ""
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Count`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Mm`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Cm`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `M`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Inches`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Feet`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Yards`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Length`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Degrees`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Radians`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Angle`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Known`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Default`| | No |
|
||||||
|
| `len` |[`UnitLen`](/docs/kcl/types/UnitLen)| | No |
|
||||||
|
| `angle` |[`UnitAngle`](/docs/kcl/types/UnitAngle)| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Unknown`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Any`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -98,6 +98,29 @@ a complete arc
|
|||||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
A base path.
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `CircleThreePoint`| | No |
|
||||||
|
| `p1` |`[number, number]`| Point 1 of the circle | No |
|
||||||
|
| `p2` |`[number, number]`| Point 2 of the circle | No |
|
||||||
|
| `p3` |`[number, number]`| Point 3 of the circle | No |
|
||||||
|
| `from` |`[number, number]`| The from point. | No |
|
||||||
|
| `to` |`[number, number]`| The to point. | No |
|
||||||
|
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||||
|
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
A path that is horizontal.
|
A path that is horizontal.
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ A plane.
|
|||||||
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
||||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A plane. | No |
|
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A plane. | No |
|
||||||
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
||||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
|
||||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
|
||||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A plane. | No |
|
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A plane. | No |
|
||||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||||
|
@ -17,6 +17,5 @@ layout: manual
|
|||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `environments` |`[` [`Environment`](/docs/kcl/types/Environment) `]`| | No |
|
| `environments` |`[` [`Environment`](/docs/kcl/types/Environment) `]`| | No |
|
||||||
| `currentEnv` |`integer`| | No |
|
| `currentEnv` |`integer`| | No |
|
||||||
| `return` |[`KclValue`](/docs/kcl/types/KclValue)| | No |
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ A plane.
|
|||||||
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
||||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A sketch type. | No |
|
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A sketch type. | No |
|
||||||
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
||||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
|
||||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
|
||||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
|
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
|
||||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||||
@ -53,8 +53,8 @@ A face.
|
|||||||
| `id` |`string`| The id of the face. | No |
|
| `id` |`string`| The id of the face. | No |
|
||||||
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
|
||||||
| `value` |`string`| The tag of the face. | No |
|
| `value` |`string`| The tag of the face. | No |
|
||||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s X axis be? | No |
|
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No |
|
||||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s Y axis be? | No |
|
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
|
||||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||||
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
||||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
|
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
|
||||||
|
16
docs/kcl/types/SnapshotRef.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
title: "SnapshotRef"
|
||||||
|
excerpt: "An index pointing to a snapshot within a specific (unspecified) environment."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
An index pointing to a snapshot within a specific (unspecified) environment.
|
||||||
|
|
||||||
|
**Type:** `integer` (`uint`)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
47
docs/kcl/types/UnitAngle.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
title: "UnitAngle"
|
||||||
|
excerpt: ""
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Degrees`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Radians`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
186
docs/kcl/types/UnitType.md
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
---
|
||||||
|
title: "UnitType"
|
||||||
|
excerpt: ""
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Count`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Mm`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Cm`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `M`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Inches`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Feet`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Yards`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Length`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**This schema accepts exactly one of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Degrees`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Type:** `object`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Radians`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description | Required |
|
||||||
|
|----------|------|-------------|----------|
|
||||||
|
| `type` |enum: `Angle`| | No |
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -54,23 +54,26 @@ async function doBasicSketch(
|
|||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
await expect(u.codeLocator).toContainText(
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)`)
|
`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
await expect(u.codeLocator)
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|
||||||
|> xLine(${commonPoints.num1}, %)`)
|
|> xLine(${commonPoints.num1}, %)`)
|
||||||
}
|
}
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
await expect(u.codeLocator)
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
|
||||||
|
commonPoints.startAt
|
||||||
|
}, sketch001)
|
||||||
|> xLine(${commonPoints.num1}, %)
|
|> xLine(${commonPoints.num1}, %)
|
||||||
|> yLine(${commonPoints.num1 + 0.01}, %)`)
|
|> yLine(${commonPoints.num1 + 0.01}, %)`)
|
||||||
} else {
|
} else {
|
||||||
@ -79,8 +82,10 @@ async function doBasicSketch(
|
|||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
await expect(u.codeLocator)
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
|
||||||
|
commonPoints.startAt
|
||||||
|
}, sketch001)
|
||||||
|> xLine(${commonPoints.num1}, %)
|
|> xLine(${commonPoints.num1}, %)
|
||||||
|> yLine(${commonPoints.num1 + 0.01}, %)
|
|> yLine(${commonPoints.num1 + 0.01}, %)
|
||||||
|> xLine(${commonPoints.num2 * -1}, %)`)
|
|> xLine(${commonPoints.num2 * -1}, %)`)
|
||||||
@ -137,8 +142,10 @@ async function doBasicSketch(
|
|||||||
|
|
||||||
// Open the code pane.
|
// Open the code pane.
|
||||||
await u.openKclCodePanel()
|
await u.openKclCodePanel()
|
||||||
await expect(u.codeLocator).toHaveText(`sketch001 = startSketchOn('XZ')
|
await expect(u.codeLocator)
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
|
||||||
|
commonPoints.startAt
|
||||||
|
}, sketch001)
|
||||||
|> xLine(${commonPoints.num1}, %, $seg01)
|
|> xLine(${commonPoints.num1}, %, $seg01)
|
||||||
|> yLine(${commonPoints.num1 + 0.01}, %)
|
|> yLine(${commonPoints.num1 + 0.01}, %)
|
||||||
|> xLine(-segLen(seg01), %)`)
|
|> xLine(-segLen(seg01), %)`)
|
||||||
|
@ -43,8 +43,7 @@ test.describe(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = `sketch001 = startSketchOn('${plane}')
|
const code = `sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.9, -1.22], sketch001)`
|
||||||
|> startProfileAt([0.9, -1.22], %)`
|
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ sketch001 = startSketchOn('XZ')
|
|||||||
revolve001 = revolve({ axis = "X" }, sketch001)
|
revolve001 = revolve({ axis = "X" }, sketch001)
|
||||||
triangle()
|
triangle()
|
||||||
|> extrude(length = 30)
|
|> extrude(length = 30)
|
||||||
plane001 = offsetPlane('XY', 10)
|
plane001 = offsetPlane('XY', offset = 10)
|
||||||
sketch002 = startSketchOn(plane001)
|
sketch002 = startSketchOn(plane001)
|
||||||
|> startProfileAt([-20, 0], %)
|
|> startProfileAt([-20, 0], %)
|
||||||
|> line(end = [5, -15])
|
|> line(end = [5, -15])
|
||||||
@ -35,7 +35,7 @@ sketch002 = startSketchOn(plane001)
|
|||||||
extrude001 = extrude(sketch002, length = 10)
|
extrude001 = extrude(sketch002, length = 10)
|
||||||
`
|
`
|
||||||
|
|
||||||
const FEAUTRE_TREE_SKETCH_CODE = `sketch001 = startSketchOn('XZ')
|
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine([0, 4], %, $rectangleSegmentA001)
|
|> angledLine([0, 4], %, $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine([
|
||||||
@ -54,7 +54,7 @@ sketch002 = startSketchOn(extrude001, rectangleSegmentB001)
|
|||||||
center = [-1, 2],
|
center = [-1, 2],
|
||||||
radius = .5
|
radius = .5
|
||||||
}, %)
|
}, %)
|
||||||
plane001 = offsetPlane('XZ', -5)
|
plane001 = offsetPlane('XZ', offset = -5)
|
||||||
sketch003 = startSketchOn(plane001)
|
sketch003 = startSketchOn(plane001)
|
||||||
|> circle({ center = [0, 0], radius = 5 }, %)
|
|> circle({ center = [0, 0], radius = 5 }, %)
|
||||||
`
|
`
|
||||||
@ -116,7 +116,7 @@ test.describe('Feature Tree pane', () => {
|
|||||||
await testViewSource({
|
await testViewSource({
|
||||||
operationName: 'Offset Plane',
|
operationName: 'Offset Plane',
|
||||||
operationIndex: 0,
|
operationIndex: 0,
|
||||||
expectedActiveLine: "plane001 = offsetPlane('XY', 10)",
|
expectedActiveLine: "plane001 = offsetPlane('XY', offset = 10)",
|
||||||
})
|
})
|
||||||
await testViewSource({
|
await testViewSource({
|
||||||
operationName: 'Extrude',
|
operationName: 'Extrude',
|
||||||
@ -153,33 +153,16 @@ test.describe('Feature Tree pane', () => {
|
|||||||
`User can edit sketch (but not on offset plane yet) from the feature tree`,
|
`User can edit sketch (but not on offset plane yet) from the feature tree`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, homePage, scene, editor, toolbar, page }) => {
|
async ({ context, homePage, scene, editor, toolbar, page }) => {
|
||||||
const unavailableToastMessage = page.getByText(
|
await context.addInitScript((initialCode) => {
|
||||||
'Editing sketches on faces or offset planes through the feature tree is not yet supported'
|
localStorage.setItem('persistCode', initialCode)
|
||||||
)
|
}, FEATURE_TREE_SKETCH_CODE)
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
await test.step('force re-exe', async () => {
|
||||||
const bracketDir = join(dir, 'test-sample')
|
await page.waitForTimeout(1000)
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await editor.replaceCode('90', '91')
|
||||||
await fsp.writeFile(
|
await page.waitForTimeout(1500)
|
||||||
join(bracketDir, 'main.kcl'),
|
|
||||||
FEAUTRE_TREE_SKETCH_CODE,
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('setup test', async () => {
|
|
||||||
await homePage.expectState({
|
|
||||||
projectCards: [
|
|
||||||
{
|
|
||||||
title: 'test-sample',
|
|
||||||
fileCount: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sortBy: 'last-modified-desc',
|
|
||||||
})
|
|
||||||
await homePage.openProject('test-sample')
|
|
||||||
await scene.waitForExecutionDone()
|
|
||||||
await toolbar.openFeatureTreePane()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('On a default plane should work', async () => {
|
await test.step('On a default plane should work', async () => {
|
||||||
@ -199,24 +182,23 @@ test.describe('Feature Tree pane', () => {
|
|||||||
await test.step('On an extrude face should *not* work', async () => {
|
await test.step('On an extrude face should *not* work', async () => {
|
||||||
// Tooltip is getting in the way of clicking, so I'm first closing the pane
|
// Tooltip is getting in the way of clicking, so I'm first closing the pane
|
||||||
await toolbar.closeFeatureTreePane()
|
await toolbar.closeFeatureTreePane()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
await editor.replaceCode('91', '90')
|
||||||
|
await page.waitForTimeout(2000)
|
||||||
await (await toolbar.getFeatureTreeOperation('Sketch', 1)).dblclick()
|
await (await toolbar.getFeatureTreeOperation('Sketch', 1)).dblclick()
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
unavailableToastMessage,
|
toolbar.exitSketchBtn,
|
||||||
'We should see a toast message about this'
|
'We should be in sketch mode now'
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
await unavailableToastMessage.waitFor({ state: 'detached' })
|
await editor.expectState({
|
||||||
// TODO - turn on once we update the artifactGraph in Rust
|
highlightedCode: '',
|
||||||
// to include the proper source location for the extrude face
|
diagnostics: [],
|
||||||
// await expect(
|
activeLines: [
|
||||||
// toolbar.exitSketchBtn,
|
'sketch002=startSketchOn(extrude001,rectangleSegmentB001)',
|
||||||
// 'We should be in sketch mode now'
|
],
|
||||||
// ).toBeVisible()
|
})
|
||||||
// await editor.expectState({
|
await toolbar.exitSketchBtn.click()
|
||||||
// highlightedCode: '',
|
|
||||||
// diagnostics: [],
|
|
||||||
// activeLines: ['|>circle({center=[-1,2],radius=.5},%)'],
|
|
||||||
// })
|
|
||||||
// await toolbar.exitSketchBtn.click()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('On an offset plane should *not* work', async () => {
|
await test.step('On an offset plane should *not* work', async () => {
|
||||||
@ -226,7 +208,7 @@ test.describe('Feature Tree pane', () => {
|
|||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
activeLines: ['|>circle({center=[0,0],radius=5},%)'],
|
activeLines: ['sketch003=startSketchOn(plane001)'],
|
||||||
})
|
})
|
||||||
await expect(
|
await expect(
|
||||||
toolbar.exitSketchBtn,
|
toolbar.exitSketchBtn,
|
||||||
@ -342,7 +324,8 @@ test.describe('Feature Tree pane', () => {
|
|||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const testCode = (value: string) => `p = offsetPlane('XY', ${value})`
|
const testCode = (value: string) =>
|
||||||
|
`p = offsetPlane('XY', offset = ${value})`
|
||||||
const initialInput = '10'
|
const initialInput = '10'
|
||||||
const initialCode = testCode(initialInput)
|
const initialCode = testCode(initialInput)
|
||||||
const newInput = '5 + 10'
|
const newInput = '5 + 10'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Page, Locator } from '@playwright/test'
|
import type { Page, Locator } from '@playwright/test'
|
||||||
import { expect } from '@playwright/test'
|
import { expect } from '@playwright/test'
|
||||||
import { uuidv4 } from 'lib/utils'
|
import { isArray, uuidv4 } from 'lib/utils'
|
||||||
import {
|
import {
|
||||||
closeDebugPanel,
|
closeDebugPanel,
|
||||||
doAndWaitForImageDiff,
|
doAndWaitForImageDiff,
|
||||||
@ -9,13 +9,15 @@ import {
|
|||||||
sendCustomCmd,
|
sendCustomCmd,
|
||||||
} from '../test-utils'
|
} from '../test-utils'
|
||||||
|
|
||||||
type mouseParams = {
|
type MouseParams = {
|
||||||
pixelDiff?: number
|
pixelDiff?: number
|
||||||
|
shouldDbClick?: boolean
|
||||||
|
delay?: number
|
||||||
}
|
}
|
||||||
type mouseDragToParams = mouseParams & {
|
type MouseDragToParams = MouseParams & {
|
||||||
fromPoint: { x: number; y: number }
|
fromPoint: { x: number; y: number }
|
||||||
}
|
}
|
||||||
type mouseDragFromParams = mouseParams & {
|
type MouseDragFromParams = MouseParams & {
|
||||||
toPoint: { x: number; y: number }
|
toPoint: { x: number; y: number }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,12 +28,12 @@ type SceneSerialised = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClickHandler = (clickParams?: mouseParams) => Promise<void | boolean>
|
type ClickHandler = (clickParams?: MouseParams) => Promise<void | boolean>
|
||||||
type MoveHandler = (moveParams?: mouseParams) => Promise<void | boolean>
|
type MoveHandler = (moveParams?: MouseParams) => Promise<void | boolean>
|
||||||
type DblClickHandler = (clickParams?: mouseParams) => Promise<void | boolean>
|
type DblClickHandler = (clickParams?: MouseParams) => Promise<void | boolean>
|
||||||
type DragToHandler = (dragParams: mouseDragToParams) => Promise<void | boolean>
|
type DragToHandler = (dragParams: MouseDragToParams) => Promise<void | boolean>
|
||||||
type DragFromHandler = (
|
type DragFromHandler = (
|
||||||
dragParams: mouseDragFromParams
|
dragParams: MouseDragFromParams
|
||||||
) => Promise<void | boolean>
|
) => Promise<void | boolean>
|
||||||
|
|
||||||
export class SceneFixture {
|
export class SceneFixture {
|
||||||
@ -77,17 +79,26 @@ export class SceneFixture {
|
|||||||
{ steps }: { steps: number } = { steps: 20 }
|
{ steps }: { steps: number } = { steps: 20 }
|
||||||
): [ClickHandler, MoveHandler, DblClickHandler] =>
|
): [ClickHandler, MoveHandler, DblClickHandler] =>
|
||||||
[
|
[
|
||||||
(clickParams?: mouseParams) => {
|
(clickParams?: MouseParams) => {
|
||||||
if (clickParams?.pixelDiff) {
|
if (clickParams?.pixelDiff) {
|
||||||
return doAndWaitForImageDiff(
|
return doAndWaitForImageDiff(
|
||||||
this.page,
|
this.page,
|
||||||
() => this.page.mouse.click(x, y),
|
() =>
|
||||||
|
clickParams?.shouldDbClick
|
||||||
|
? this.page.mouse.dblclick(x, y, {
|
||||||
|
delay: clickParams?.delay || 0,
|
||||||
|
})
|
||||||
|
: this.page.mouse.click(x, y, {
|
||||||
|
delay: clickParams?.delay || 0,
|
||||||
|
}),
|
||||||
clickParams.pixelDiff
|
clickParams.pixelDiff
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return this.page.mouse.click(x, y)
|
return clickParams?.shouldDbClick
|
||||||
|
? this.page.mouse.dblclick(x, y, { delay: clickParams?.delay || 0 })
|
||||||
|
: this.page.mouse.click(x, y, { delay: clickParams?.delay || 0 })
|
||||||
},
|
},
|
||||||
(moveParams?: mouseParams) => {
|
(moveParams?: MouseParams) => {
|
||||||
if (moveParams?.pixelDiff) {
|
if (moveParams?.pixelDiff) {
|
||||||
return doAndWaitForImageDiff(
|
return doAndWaitForImageDiff(
|
||||||
this.page,
|
this.page,
|
||||||
@ -97,7 +108,7 @@ export class SceneFixture {
|
|||||||
}
|
}
|
||||||
return this.page.mouse.move(x, y, { steps })
|
return this.page.mouse.move(x, y, { steps })
|
||||||
},
|
},
|
||||||
(clickParams?: mouseParams) => {
|
(clickParams?: MouseParams) => {
|
||||||
if (clickParams?.pixelDiff) {
|
if (clickParams?.pixelDiff) {
|
||||||
return doAndWaitForImageDiff(
|
return doAndWaitForImageDiff(
|
||||||
this.page,
|
this.page,
|
||||||
@ -114,7 +125,7 @@ export class SceneFixture {
|
|||||||
{ steps }: { steps: number } = { steps: 20 }
|
{ steps }: { steps: number } = { steps: 20 }
|
||||||
): [DragToHandler, DragFromHandler] =>
|
): [DragToHandler, DragFromHandler] =>
|
||||||
[
|
[
|
||||||
(dragToParams: mouseDragToParams) => {
|
(dragToParams: MouseDragToParams) => {
|
||||||
if (dragToParams?.pixelDiff) {
|
if (dragToParams?.pixelDiff) {
|
||||||
return doAndWaitForImageDiff(
|
return doAndWaitForImageDiff(
|
||||||
this.page,
|
this.page,
|
||||||
@ -131,7 +142,7 @@ export class SceneFixture {
|
|||||||
targetPosition: { x, y },
|
targetPosition: { x, y },
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
(dragFromParams: mouseDragFromParams) => {
|
(dragFromParams: MouseDragFromParams) => {
|
||||||
if (dragFromParams?.pixelDiff) {
|
if (dragFromParams?.pixelDiff) {
|
||||||
return doAndWaitForImageDiff(
|
return doAndWaitForImageDiff(
|
||||||
this.page,
|
this.page,
|
||||||
@ -219,7 +230,7 @@ export class SceneFixture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expectPixelColor = async (
|
expectPixelColor = async (
|
||||||
colour: [number, number, number],
|
colour: [number, number, number] | [number, number, number][],
|
||||||
coords: { x: number; y: number },
|
coords: { x: number; y: number },
|
||||||
diff: number
|
diff: number
|
||||||
) => {
|
) => {
|
||||||
@ -241,22 +252,36 @@ export class SceneFixture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isColourArray(
|
||||||
|
colour: [number, number, number] | [number, number, number][]
|
||||||
|
): colour is [number, number, number][] {
|
||||||
|
return isArray(colour[0])
|
||||||
|
}
|
||||||
|
|
||||||
export async function expectPixelColor(
|
export async function expectPixelColor(
|
||||||
page: Page,
|
page: Page,
|
||||||
colour: [number, number, number],
|
colour: [number, number, number] | [number, number, number][],
|
||||||
coords: { x: number; y: number },
|
coords: { x: number; y: number },
|
||||||
diff: number
|
diff: number
|
||||||
) {
|
) {
|
||||||
let finalValue = colour
|
let finalValue = colour
|
||||||
await expect
|
await expect
|
||||||
.poll(async () => {
|
.poll(
|
||||||
const pixel = (await getPixelRGBs(page)(coords, 1))[0]
|
async () => {
|
||||||
if (!pixel) return null
|
const pixel = (await getPixelRGBs(page)(coords, 1))[0]
|
||||||
finalValue = pixel
|
if (!pixel) return null
|
||||||
return pixel.every(
|
finalValue = pixel
|
||||||
(channel, index) => Math.abs(channel - colour[index]) < diff
|
if (!isColourArray(colour)) {
|
||||||
)
|
return pixel.every(
|
||||||
})
|
(channel, index) => Math.abs(channel - colour[index]) < diff
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return colour.some((c) =>
|
||||||
|
c.every((channel, index) => Math.abs(pixel[index] - channel) < diff)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{ timeout: 10_000 }
|
||||||
|
)
|
||||||
.toBeTruthy()
|
.toBeTruthy()
|
||||||
.catch((cause) => {
|
.catch((cause) => {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -23,7 +23,10 @@ export class ToolbarFixture {
|
|||||||
helixButton!: Locator
|
helixButton!: Locator
|
||||||
startSketchBtn!: Locator
|
startSketchBtn!: Locator
|
||||||
lineBtn!: Locator
|
lineBtn!: Locator
|
||||||
|
tangentialArcBtn!: Locator
|
||||||
|
circleBtn!: Locator
|
||||||
rectangleBtn!: Locator
|
rectangleBtn!: Locator
|
||||||
|
lengthConstraintBtn!: Locator
|
||||||
exitSketchBtn!: Locator
|
exitSketchBtn!: Locator
|
||||||
editSketchBtn!: Locator
|
editSketchBtn!: Locator
|
||||||
fileTreeBtn!: Locator
|
fileTreeBtn!: Locator
|
||||||
@ -53,7 +56,10 @@ export class ToolbarFixture {
|
|||||||
this.helixButton = page.getByTestId('helix')
|
this.helixButton = page.getByTestId('helix')
|
||||||
this.startSketchBtn = page.getByTestId('sketch')
|
this.startSketchBtn = page.getByTestId('sketch')
|
||||||
this.lineBtn = page.getByTestId('line')
|
this.lineBtn = page.getByTestId('line')
|
||||||
|
this.tangentialArcBtn = page.getByTestId('tangential-arc')
|
||||||
|
this.circleBtn = page.getByTestId('circle-center')
|
||||||
this.rectangleBtn = page.getByTestId('corner-rectangle')
|
this.rectangleBtn = page.getByTestId('corner-rectangle')
|
||||||
|
this.lengthConstraintBtn = page.getByTestId('constraint-length')
|
||||||
this.exitSketchBtn = page.getByTestId('sketch-exit')
|
this.exitSketchBtn = page.getByTestId('sketch-exit')
|
||||||
this.editSketchBtn = page.getByText('Edit Sketch')
|
this.editSketchBtn = page.getByText('Edit Sketch')
|
||||||
this.fileTreeBtn = page.locator('[id="files-button-holder"]')
|
this.fileTreeBtn = page.locator('[id="files-button-holder"]')
|
||||||
@ -119,6 +125,25 @@ export class ToolbarFixture {
|
|||||||
await expect(this.exeIndicator).toBeVisible({ timeout: 15_000 })
|
await expect(this.exeIndicator).toBeVisible({ timeout: 15_000 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
selectCenterRectangle = async () => {
|
||||||
|
await this.page
|
||||||
|
.getByRole('button', { name: 'caret down Corner rectangle:' })
|
||||||
|
.click()
|
||||||
|
await expect(
|
||||||
|
this.page.getByTestId('dropdown-center-rectangle')
|
||||||
|
).toBeVisible()
|
||||||
|
await this.page.getByTestId('dropdown-center-rectangle').click()
|
||||||
|
}
|
||||||
|
|
||||||
|
selectCircleThreePoint = async () => {
|
||||||
|
await this.page
|
||||||
|
.getByRole('button', { name: 'caret down Center circle:' })
|
||||||
|
.click()
|
||||||
|
await expect(
|
||||||
|
this.page.getByTestId('dropdown-circle-three-points')
|
||||||
|
).toBeVisible()
|
||||||
|
await this.page.getByTestId('dropdown-circle-three-points').click()
|
||||||
|
}
|
||||||
|
|
||||||
async closePane(paneId: SidebarType) {
|
async closePane(paneId: SidebarType) {
|
||||||
return closePane(this.page, paneId + SIDEBAR_BUTTON_SUFFIX)
|
return closePane(this.page, paneId + SIDEBAR_BUTTON_SUFFIX)
|
||||||
|
@ -219,18 +219,13 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
|||||||
|
|
||||||
afterChamferSelectSnippet:
|
afterChamferSelectSnippet:
|
||||||
'sketch002 = startSketchOn(extrude001, seg03)',
|
'sketch002 = startSketchOn(extrude001, seg03)',
|
||||||
afterRectangle1stClickSnippet: 'startProfileAt([205.96, 254.59], %)',
|
afterRectangle1stClickSnippet:
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0, 11.39], %, $rectangleSegmentA002)
|
'startProfileAt([205.96, 254.59], sketch002)',
|
||||||
|> angledLine([
|
afterRectangle2ndClickSnippet: `angledLine([0,11.39],%,$rectangleSegmentA002)
|
||||||
segAng(rectangleSegmentA002) - 90,
|
|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)
|
||||||
105.26
|
|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)
|
||||||
], %, $rectangleSegmentB001)
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|> angledLine([
|
|>close()`,
|
||||||
segAng(rectangleSegmentA002),
|
|
||||||
-segLen(rectangleSegmentA002)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await sketchOnAChamfer({
|
await sketchOnAChamfer({
|
||||||
@ -251,19 +246,15 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
|||||||
|
|
||||||
afterChamferSelectSnippet:
|
afterChamferSelectSnippet:
|
||||||
'sketch003 = startSketchOn(extrude001, seg04)',
|
'sketch003 = startSketchOn(extrude001, seg04)',
|
||||||
afterRectangle1stClickSnippet: 'startProfileAt([-209.64, 255.28], %)',
|
afterRectangle1stClickSnippet:
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0, 11.56], %, $rectangleSegmentA003)
|
'startProfileAt([-209.64, 255.28], sketch003)',
|
||||||
|> angledLine([
|
afterRectangle2ndClickSnippet: `angledLine([0,11.56],%,$rectangleSegmentA003)
|
||||||
segAng(rectangleSegmentA003) - 90,
|
|>angledLine([segAng(rectangleSegmentA003)-90,106.84],%)
|
||||||
106.84
|
|>angledLine([segAng(rectangleSegmentA003),-segLen(rectangleSegmentA003)],%)
|
||||||
], %, $rectangleSegmentB002)
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|> angledLine([
|
|>close()`,
|
||||||
segAng(rectangleSegmentA003),
|
|
||||||
-segLen(rectangleSegmentA003)
|
|
||||||
], %, $rectangleSegmentC002)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await sketchOnAChamfer({
|
await sketchOnAChamfer({
|
||||||
clickCoords: { x: 677, y: 87 },
|
clickCoords: { x: 677, y: 87 },
|
||||||
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
||||||
@ -276,19 +267,14 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
|||||||
]
|
]
|
||||||
}, %)`,
|
}, %)`,
|
||||||
afterChamferSelectSnippet:
|
afterChamferSelectSnippet:
|
||||||
'sketch003 = startSketchOn(extrude001, seg04)',
|
'sketch004 = startSketchOn(extrude001, seg05)',
|
||||||
afterRectangle1stClickSnippet: 'startProfileAt([75.8, 317.2], %)',
|
afterRectangle1stClickSnippet:
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0, 11.56], %, $rectangleSegmentA003)
|
'startProfileAt([82.57, 322.96], sketch004)',
|
||||||
|> angledLine([
|
afterRectangle2ndClickSnippet: `angledLine([0,11.16],%,$rectangleSegmentA004)
|
||||||
segAng(rectangleSegmentA003) - 90,
|
|>angledLine([segAng(rectangleSegmentA004)-90,103.07],%)
|
||||||
106.84
|
|>angledLine([segAng(rectangleSegmentA004),-segLen(rectangleSegmentA004)],%)
|
||||||
], %, $rectangleSegmentB002)
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|> angledLine([
|
|>close()`,
|
||||||
segAng(rectangleSegmentA003),
|
|
||||||
-segLen(rectangleSegmentA003)
|
|
||||||
], %, $rectangleSegmentC002)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()`,
|
|
||||||
})
|
})
|
||||||
/// last one
|
/// last one
|
||||||
await sketchOnAChamfer({
|
await sketchOnAChamfer({
|
||||||
@ -301,104 +287,98 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
|||||||
}, %)`,
|
}, %)`,
|
||||||
afterChamferSelectSnippet:
|
afterChamferSelectSnippet:
|
||||||
'sketch005 = startSketchOn(extrude001, seg06)',
|
'sketch005 = startSketchOn(extrude001, seg06)',
|
||||||
afterRectangle1stClickSnippet: 'startProfileAt([-23.43, 19.69], %)',
|
afterRectangle1stClickSnippet:
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0, 9.1], %, $rectangleSegmentA005)
|
'startProfileAt([-23.43, 19.69], sketch005)',
|
||||||
|
afterRectangle2ndClickSnippet: `angledLine([0,9.1],%,$rectangleSegmentA005)
|
||||||
|> angledLine([
|
|>angledLine([segAng(rectangleSegmentA005)-90,84.07],%)
|
||||||
segAng(rectangleSegmentA005) - 90,
|
|>angledLine([segAng(rectangleSegmentA005),-segLen(rectangleSegmentA005)],%)
|
||||||
84.07
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
], %, $rectangleSegmentB004)
|
|>close()`,
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA005),
|
|
||||||
-segLen(rectangleSegmentA005)
|
|
||||||
], %, $rectangleSegmentC004)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('verify at the end of the test that final code is what is expected', async () => {
|
await test.step('verify at the end of the test that final code is what is expected', async () => {
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')
|
||||||
|
|> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag]
|
||||||
|
|> angledLine([0, 268.43], %, $rectangleSegmentA001)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001) - 90,
|
||||||
|
217.26
|
||||||
|
], %, $seg01)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001),
|
||||||
|
-segLen(rectangleSegmentA001)
|
||||||
|
], %, $yo)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|
|> close()
|
||||||
|
extrude001 = extrude(sketch001, length = 100)
|
||||||
|
|> chamfer({
|
||||||
|
length = 30,
|
||||||
|
tags = [getOppositeEdge(seg01)]
|
||||||
|
}, %, $seg03)
|
||||||
|
|> chamfer({ length = 30, tags = [seg01] }, %, $seg04)
|
||||||
|
|> chamfer({
|
||||||
|
length = 30,
|
||||||
|
tags = [getNextAdjacentEdge(seg02)]
|
||||||
|
}, %, $seg05)
|
||||||
|
|> chamfer({
|
||||||
|
length = 30,
|
||||||
|
tags = [getNextAdjacentEdge(yo)]
|
||||||
|
}, %, $seg06)
|
||||||
|
sketch005 = startSketchOn(extrude001, seg06)
|
||||||
|
profile004 = startProfileAt([-23.43, 19.69], sketch005)
|
||||||
|
|> angledLine([0, 9.1], %, $rectangleSegmentA005)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA005) - 90,
|
||||||
|
84.07
|
||||||
|
], %)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA005),
|
||||||
|
-segLen(rectangleSegmentA005)
|
||||||
|
], %)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
sketch004 = startSketchOn(extrude001, seg05)
|
||||||
|
profile003 = startProfileAt([82.57, 322.96], sketch004)
|
||||||
|
|> angledLine([0, 11.16], %, $rectangleSegmentA004)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA004) - 90,
|
||||||
|
103.07
|
||||||
|
], %)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA004),
|
||||||
|
-segLen(rectangleSegmentA004)
|
||||||
|
], %)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
sketch003 = startSketchOn(extrude001, seg04)
|
||||||
|
profile002 = startProfileAt([-209.64, 255.28], sketch003)
|
||||||
|
|> angledLine([0, 11.56], %, $rectangleSegmentA003)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA003) - 90,
|
||||||
|
106.84
|
||||||
|
], %)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA003),
|
||||||
|
-segLen(rectangleSegmentA003)
|
||||||
|
], %)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
sketch002 = startSketchOn(extrude001, seg03)
|
||||||
|
profile001 = startProfileAt([205.96, 254.59], sketch002)
|
||||||
|
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA002) - 90,
|
||||||
|
105.26
|
||||||
|
], %)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA002),
|
||||||
|
-segLen(rectangleSegmentA002)
|
||||||
|
], %)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
|
||||||
|> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag]
|
`,
|
||||||
|> angledLine([0, 268.43], %, $rectangleSegmentA001)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|
||||||
217.26
|
|
||||||
], %, $seg01)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $yo)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|
||||||
|> close()
|
|
||||||
extrude001 = extrude(sketch001, length = 100)
|
|
||||||
|> chamfer({
|
|
||||||
length = 30,
|
|
||||||
tags = [getOppositeEdge(seg01)]
|
|
||||||
}, %, $seg03)
|
|
||||||
|> chamfer({ length = 30, tags = [seg01] }, %, $seg04)
|
|
||||||
|> chamfer({
|
|
||||||
length = 30,
|
|
||||||
tags = [getNextAdjacentEdge(seg02)]
|
|
||||||
}, %, $seg05)
|
|
||||||
|> chamfer({
|
|
||||||
length = 30,
|
|
||||||
tags = [getNextAdjacentEdge(yo)]
|
|
||||||
}, %, $seg06)
|
|
||||||
sketch005 = startSketchOn(extrude001, seg06)
|
|
||||||
|> startProfileAt([-23.43,19.69], %)
|
|
||||||
|> angledLine([0, 9.1], %, $rectangleSegmentA005)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA005) - 90,
|
|
||||||
84.07
|
|
||||||
], %, $rectangleSegmentB004)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA005),
|
|
||||||
-segLen(rectangleSegmentA005)
|
|
||||||
], %, $rectangleSegmentC004)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
sketch004 = startSketchOn(extrude001, seg05)
|
|
||||||
|> startProfileAt([82.57,322.96], %)
|
|
||||||
|> angledLine([0, 11.16], %, $rectangleSegmentA004)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA004) - 90,
|
|
||||||
103.07
|
|
||||||
], %, $rectangleSegmentB003)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA004),
|
|
||||||
-segLen(rectangleSegmentA004)
|
|
||||||
], %, $rectangleSegmentC003)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
sketch003 = startSketchOn(extrude001, seg04)
|
|
||||||
|> startProfileAt([-209.64,255.28], %)
|
|
||||||
|> angledLine([0, 11.56], %, $rectangleSegmentA003)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA003) - 90,
|
|
||||||
106.84
|
|
||||||
], %, $rectangleSegmentB002)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA003),
|
|
||||||
-segLen(rectangleSegmentA003)
|
|
||||||
], %, $rectangleSegmentC002)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
sketch002 = startSketchOn(extrude001, seg03)
|
|
||||||
|> startProfileAt([205.96,254.59], %)
|
|
||||||
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA002) - 90,
|
|
||||||
105.26
|
|
||||||
], %, $rectangleSegmentB001)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA002),
|
|
||||||
-segLen(rectangleSegmentA002)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -443,18 +423,13 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
|||||||
beforeChamferSnippetEnd: '}, extrude001)',
|
beforeChamferSnippetEnd: '}, extrude001)',
|
||||||
afterChamferSelectSnippet:
|
afterChamferSelectSnippet:
|
||||||
'sketch002 = startSketchOn(extrude001, seg03)',
|
'sketch002 = startSketchOn(extrude001, seg03)',
|
||||||
afterRectangle1stClickSnippet: 'startProfileAt([205.96, 254.59], %)',
|
afterRectangle1stClickSnippet:
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0, 11.39], %, $rectangleSegmentA002)
|
'startProfileAt([205.96, 254.59], sketch002)',
|
||||||
|> angledLine([
|
afterRectangle2ndClickSnippet: `angledLine([0,11.39],%,$rectangleSegmentA002)
|
||||||
segAng(rectangleSegmentA002) - 90,
|
|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)
|
||||||
105.26
|
|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)
|
||||||
], %, $rectangleSegmentB001)
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|> angledLine([
|
|>close()`,
|
||||||
segAng(rectangleSegmentA002),
|
|
||||||
-segLen(rectangleSegmentA002)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()`,
|
|
||||||
})
|
})
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')
|
||||||
@ -484,17 +459,17 @@ chamf = chamfer({
|
|||||||
]
|
]
|
||||||
}, %)
|
}, %)
|
||||||
sketch002 = startSketchOn(extrude001, seg03)
|
sketch002 = startSketchOn(extrude001, seg03)
|
||||||
|> startProfileAt([205.96, 254.59], %)
|
profile001 = startProfileAt([205.96, 254.59], sketch002)
|
||||||
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
|
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
|
||||||
|> angledLine([
|
|> angledLine([
|
||||||
segAng(rectangleSegmentA002) - 90,
|
segAng(rectangleSegmentA002) - 90,
|
||||||
105.26
|
105.26
|
||||||
], %, $rectangleSegmentB001)
|
], %)
|
||||||
|> angledLine([
|
|> angledLine([
|
||||||
segAng(rectangleSegmentA002),
|
segAng(rectangleSegmentA002),
|
||||||
-segLen(rectangleSegmentA002)
|
-segLen(rectangleSegmentA002)
|
||||||
], %, $rectangleSegmentC001)
|
], %)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute=[profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
`,
|
`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
@ -561,10 +536,10 @@ sketch002 = startSketchOn(extrude001, seg03)
|
|||||||
|
|
||||||
const expectedCodeSnippets = {
|
const expectedCodeSnippets = {
|
||||||
sketchOnXzPlane: `sketch001 = startSketchOn('XZ')`,
|
sketchOnXzPlane: `sketch001 = startSketchOn('XZ')`,
|
||||||
pointAtOrigin: `startProfileAt([${originSloppy.kcl[0]}, ${originSloppy.kcl[1]}], %)`,
|
pointAtOrigin: `startProfileAt([${originSloppy.kcl[0]}, ${originSloppy.kcl[1]}], sketch001)`,
|
||||||
segmentOnXAxis: `xLine(${xAxisSloppy.kcl[0]}, %)`,
|
segmentOnXAxis: `xLine(${xAxisSloppy.kcl[0]}, %)`,
|
||||||
afterSegmentDraggedOffYAxis: `startProfileAt([${offYAxis.kcl[0]}, ${offYAxis.kcl[1]}], %)`,
|
afterSegmentDraggedOffYAxis: `startProfileAt([${offYAxis.kcl[0]}, ${offYAxis.kcl[1]}], sketch001)`,
|
||||||
afterSegmentDraggedOnYAxis: `startProfileAt([${yAxisSloppy.kcl[0]}, ${yAxisSloppy.kcl[1]}], %)`,
|
afterSegmentDraggedOnYAxis: `startProfileAt([${yAxisSloppy.kcl[0]}, ${yAxisSloppy.kcl[1]}], sketch001)`,
|
||||||
}
|
}
|
||||||
|
|
||||||
await test.step(`Start a sketch on the XZ plane`, async () => {
|
await test.step(`Start a sketch on the XZ plane`, async () => {
|
||||||
@ -605,6 +580,7 @@ sketch002 = startSketchOn(extrude001, seg03)
|
|||||||
expectedCodeSnippets.afterSegmentDraggedOnYAxis
|
expectedCodeSnippets.afterSegmentDraggedOnYAxis
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
await editor.page.waitForTimeout(1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`Verify user can double-click to edit a sketch`, async ({
|
test(`Verify user can double-click to edit a sketch`, async ({
|
||||||
@ -1052,7 +1028,7 @@ openSketch = startSketchOn('XY')
|
|||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 700, y: 150 }
|
const testPoint = { x: 700, y: 150 }
|
||||||
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||||
const expectedOutput = `plane001 = offsetPlane('XZ', 5)`
|
const expectedOutput = `plane001 = offsetPlane('XZ', offset = 5)`
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
// FIXME: Since there is no KCL code loaded. We need to wait for the scene to load before we continue.
|
// FIXME: Since there is no KCL code loaded. We need to wait for the scene to load before we continue.
|
||||||
@ -1117,13 +1093,14 @@ openSketch = startSketchOn('XY')
|
|||||||
}) => {
|
}) => {
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 620, y: 257 }
|
const testPoint = { x: 620, y: 257 }
|
||||||
const expectedOutput = `helix001 = helix(revolutions = 1, angleStart = 360, counterClockWise = false, radius = 5, axis = 'X', length = 5)`
|
const expectedOutput = `helix001 = helix( revolutions = 1, angleStart = 360, counterClockWise = false, radius = 5, axis = 'X', length = 5,)`
|
||||||
|
const expectedLine = `revolutions=1,`
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await test.step(`Look for the red of the default plane`, async () => {
|
// await test.step(`Look for the red of the default plane`, async () => {
|
||||||
await scene.expectPixelColor([96, 52, 52], testPoint, 15)
|
// await scene.expectPixelColor([96, 52, 52], testPoint, 15)
|
||||||
})
|
// })
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.helixButton.click()
|
await toolbar.helixButton.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
@ -1154,7 +1131,7 @@ openSketch = startSketchOn('XY')
|
|||||||
await editor.expectEditor.toContain(expectedOutput)
|
await editor.expectEditor.toContain(expectedOutput)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
activeLines: [expectedOutput],
|
activeLines: [expectedLine],
|
||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
})
|
})
|
||||||
// Red plane is now gone, white helix is there
|
// Red plane is now gone, white helix is there
|
||||||
@ -1187,7 +1164,7 @@ openSketch = startSketchOn('XY')
|
|||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||||
|> circle({ center = [0, 0], radius = 30 }, %)
|
|> circle({ center = [0, 0], radius = 30 }, %)
|
||||||
plane001 = offsetPlane('XZ', 50)
|
plane001 = offsetPlane('XZ', offset = 50)
|
||||||
sketch002 = startSketchOn(plane001)
|
sketch002 = startSketchOn(plane001)
|
||||||
|> circle({ center = [0, 0], radius = 20 }, %)
|
|> circle({ center = [0, 0], radius = 20 }, %)
|
||||||
`
|
`
|
||||||
@ -1273,7 +1250,7 @@ openSketch = startSketchOn('XY')
|
|||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||||
|> circle({ center = [0, 0], radius = 30 }, %)
|
|> circle({ center = [0, 0], radius = 30 }, %)
|
||||||
plane001 = offsetPlane('XZ', 50)
|
plane001 = offsetPlane('XZ', offset = 50)
|
||||||
sketch002 = startSketchOn(plane001)
|
sketch002 = startSketchOn(plane001)
|
||||||
|> circle({ center = [0, 0], radius = 20 }, %)
|
|> circle({ center = [0, 0], radius = 20 }, %)
|
||||||
loft001 = loft([sketch001, sketch002])
|
loft001 = loft([sketch001, sketch002])
|
||||||
@ -1320,7 +1297,7 @@ loft001 = loft([sketch001, sketch002])
|
|||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
await clickOnSketch2()
|
await clickOnSketch2()
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
||||||
plane001 = offsetPlane('XZ', 50)
|
plane001 = offsetPlane('XZ', offset = 50)
|
||||||
`)
|
`)
|
||||||
await page.keyboard.press('Backspace')
|
await page.keyboard.press('Backspace')
|
||||||
// Check for sketch 1
|
// Check for sketch 1
|
||||||
@ -1396,12 +1373,12 @@ sketch002 = startSketchOn('XZ')
|
|||||||
await clickOnSketch2()
|
await clickOnSketch2()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await toolbar.openPane('code')
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
await scene.expectPixelColor([135, 64, 73], testPoint, 15)
|
await scene.expectPixelColor([135, 64, 73], testPoint, 15)
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(sweepDeclaration)
|
await editor.expectEditor.toContain(sweepDeclaration)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
@ -2471,19 +2448,18 @@ extrude002 = extrude(sketch002, length = 50)
|
|||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
localStorage.setItem('persistCode', initialCode)
|
localStorage.setItem('persistCode', initialCode)
|
||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.waitForExecutionDone()
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 550, y: 295 }
|
const testPoint = { x: 580, y: 320 }
|
||||||
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||||
const shellTarget = hasExtrudesInPipe ? 'sketch002' : 'extrude002'
|
const shellTarget = hasExtrudesInPipe ? 'sketch002' : 'extrude002'
|
||||||
const shellDeclaration = `shell001 = shell(${shellTarget}, faces = ['end'], thickness = 5)`
|
const shellDeclaration = `shell001 = shell(${shellTarget}, faces = ['end'], thickness = 5)`
|
||||||
|
|
||||||
await test.step(`Look for the grey of the shape`, async () => {
|
await test.step(`Look for the grey of the shape`, async () => {
|
||||||
await toolbar.closePane('code')
|
await scene.expectPixelColor([113, 113, 113], testPoint, 15)
|
||||||
await scene.expectPixelColor([128, 128, 128], testPoint, 15)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Go through the command bar flow, selecting a cap and keeping default thickness`, async () => {
|
await test.step(`Go through the command bar flow, selecting a cap and keeping default thickness`, async () => {
|
||||||
|
@ -192,11 +192,11 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
|> line(end = [0, -1])
|
|> line(end = [0, -1])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 1)
|
|> extrude(length = 1)
|
||||||
|> patternLinear3d({
|
|> patternLinear3d(
|
||||||
axis: [1, 0, 1],
|
axis = [1, 0, 1],
|
||||||
repetitions: 3,
|
repetitions = 3,
|
||||||
distance: 6
|
distance = 6,
|
||||||
}, %)`
|
)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
@ -444,8 +444,7 @@ test(
|
|||||||
|
|
||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
code += `
|
code += `profile001 = startProfileAt([7.19, -9.7], sketch001)`
|
||||||
|> startProfileAt([7.19, -9.7], %)`
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
@ -456,7 +455,9 @@ test(
|
|||||||
mask: [page.getByTestId('model-state-indicator')],
|
mask: [page.getByTestId('model-state-indicator')],
|
||||||
})
|
})
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
const lineEndClick = () =>
|
||||||
|
page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
|
await lineEndClick()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
code += `
|
code += `
|
||||||
@ -467,6 +468,15 @@ test(
|
|||||||
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
||||||
.click()
|
.click()
|
||||||
|
|
||||||
|
// click on the end of the profile to continue it
|
||||||
|
await page.waitForTimeout(300)
|
||||||
|
await lineEndClick()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
// click to continue profile
|
||||||
|
await page.mouse.move(813, 392, { steps: 10 })
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
||||||
|
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
@ -589,8 +599,7 @@ test(
|
|||||||
mask: [page.getByTestId('model-state-indicator')],
|
mask: [page.getByTestId('model-state-indicator')],
|
||||||
})
|
})
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')profile001 = circle({ center = [14.44, -2.44], radius = 1 }, sketch001)`
|
||||||
|> circle({ center = [14.44, -2.44], radius = 1 }, %)`
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -634,8 +643,7 @@ test.describe(
|
|||||||
|
|
||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
code += `
|
code += `profile001 = startProfileAt([7.19, -9.7], sketch001)`
|
||||||
|> startProfileAt([7.19, -9.7], %)`
|
|
||||||
await expect(u.codeLocator).toHaveText(code)
|
await expect(u.codeLocator).toHaveText(code)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
@ -653,6 +661,10 @@ test.describe(
|
|||||||
.click()
|
.click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
// click to continue profile
|
||||||
|
await page.mouse.click(813, 392)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||||
|
|
||||||
code += `
|
code += `
|
||||||
@ -739,8 +751,7 @@ test.describe(
|
|||||||
|
|
||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
code += `
|
code += `profile001 = startProfileAt([182.59, -246.32], sketch001)`
|
||||||
|> startProfileAt([182.59, -246.32], %)`
|
|
||||||
await expect(u.codeLocator).toHaveText(code)
|
await expect(u.codeLocator).toHaveText(code)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
@ -758,6 +769,10 @@ test.describe(
|
|||||||
.click()
|
.click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
// click to continue profile
|
||||||
|
await page.mouse.click(813, 392)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||||
|
|
||||||
code += `
|
code += `
|
||||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
@ -1,6 +1,7 @@
|
|||||||
import { test, expect } from './zoo-test'
|
import { test, expect } from './zoo-test'
|
||||||
|
|
||||||
import { commonPoints, getUtils } from './test-utils'
|
import { commonPoints, getUtils } from './test-utils'
|
||||||
|
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||||
|
import { uuidv4 } from 'lib/utils'
|
||||||
|
|
||||||
test.describe('Test network and connection issues', () => {
|
test.describe('Test network and connection issues', () => {
|
||||||
test(
|
test(
|
||||||
@ -111,18 +112,17 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|
|
||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)`)
|
)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
|> xLine(${commonPoints.num1}, %)`)
|
||||||
|> xLine(${commonPoints.num1}, %)`)
|
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await expect(networkToggle).toContainText('Connected')
|
||||||
@ -169,7 +169,9 @@ test.describe('Test network and connection issues', () => {
|
|||||||
await page.mouse.click(100, 100)
|
await page.mouse.click(100, 100)
|
||||||
|
|
||||||
// select a line
|
// select a line
|
||||||
await page.getByText(`startProfileAt(${commonPoints.startAt}, %)`).click()
|
await page
|
||||||
|
.getByText(`startProfileAt(${commonPoints.startAt}, sketch001)`)
|
||||||
|
.click()
|
||||||
|
|
||||||
// enter sketch again
|
// enter sketch again
|
||||||
await u.doAndWaitForCmd(
|
await u.doAndWaitForCmd(
|
||||||
@ -183,11 +185,36 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|
|
||||||
await page.waitForTimeout(150)
|
await page.waitForTimeout(150)
|
||||||
|
|
||||||
|
const camCommand: EngineCommand = {
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_look_at',
|
||||||
|
center: { x: 109, y: 0, z: -152 },
|
||||||
|
vantage: { x: 115, y: -505, z: -152 },
|
||||||
|
up: { x: 0, y: 0, z: 1 },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const updateCamCommand: EngineCommand = {
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
await u.sendCustomCmd(camCommand)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.sendCustomCmd(updateCamCommand)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
// click to continue profile
|
||||||
|
await page.mouse.click(1007, 400)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
// Ensure we can continue sketching
|
// Ensure we can continue sketching
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
await expect.poll(u.normalisedEditorCode)
|
await expect.poll(u.normalisedEditorCode)
|
||||||
.toBe(`sketch001 = startSketchOn('XZ')
|
.toBe(`sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([12.34, -12.34], %)
|
profile001 = startProfileAt([12.34, -12.34], sketch001)
|
||||||
|> xLine(12.34, %)
|
|> xLine(12.34, %)
|
||||||
|> line(end = [-12.34, 12.34])
|
|> line(end = [-12.34, 12.34])
|
||||||
|
|
||||||
@ -197,7 +224,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|
|
||||||
await expect.poll(u.normalisedEditorCode)
|
await expect.poll(u.normalisedEditorCode)
|
||||||
.toBe(`sketch001 = startSketchOn('XZ')
|
.toBe(`sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([12.34, -12.34], %)
|
profile001 = startProfileAt([12.34, -12.34], sketch001)
|
||||||
|> xLine(12.34, %)
|
|> xLine(12.34, %)
|
||||||
|> line(end = [-12.34, 12.34])
|
|> line(end = [-12.34, 12.34])
|
||||||
|> xLine(-12.34, %)
|
|> xLine(-12.34, %)
|
||||||
|
@ -19,7 +19,7 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|
|||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|> line(end = [0, 20])
|
|> line(end = [0, 20])
|
||||||
|> xLine(-20, %)
|
|> xLine(-20, %)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -673,7 +673,7 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|
|||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
for (const { testName, addVariable, value, constraint } of cases) {
|
for (const { testName, addVariable, value, constraint } of cases) {
|
||||||
test(`${testName}`, async ({ context, homePage, page }) => {
|
test(`${testName}`, async ({ context, homePage, page, editor }) => {
|
||||||
// constants and locators
|
// constants and locators
|
||||||
const cmdBarKclInput = page
|
const cmdBarKclInput = page
|
||||||
.getByTestId('cmd-bar-arg-value')
|
.getByTestId('cmd-bar-arg-value')
|
||||||
@ -706,7 +706,9 @@ part002 = startSketchOn('XZ')
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await u.waitForPageLoad()
|
||||||
|
|
||||||
|
await editor.scrollToText('line(end = [74.36, 130.4])', true)
|
||||||
await page.getByText('line(end = [74.36, 130.4])').click()
|
await page.getByText('line(end = [74.36, 130.4])').click()
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
|
|
||||||
|
@ -66,33 +66,34 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)`)
|
)
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
|> xLine(${commonPoints.num1}, %)`)
|
||||||
|> xLine(${commonPoints.num1}, %)`)
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
commonPoints.startAt
|
||||||
|> xLine(${commonPoints.num1}, %)
|
}, sketch001)
|
||||||
|> yLine(${commonPoints.num1 + 0.01}, %)`)
|
|> xLine(${commonPoints.num1}, %)
|
||||||
|
|> yLine(${commonPoints.num1 + 0.01}, %)`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
|
||||||
|> startProfileAt(${commonPoints.startAt}, %)
|
commonPoints.startAt
|
||||||
|> xLine(${commonPoints.num1}, %)
|
}, sketch001)
|
||||||
|> yLine(${commonPoints.num1 + 0.01}, %)
|
|> xLine(${commonPoints.num1}, %)
|
||||||
|> xLine(${commonPoints.num2 * -1}, %)`)
|
|> yLine(${commonPoints.num1 + 0.01}, %)
|
||||||
|
|> xLine(${commonPoints.num2 * -1}, %)`)
|
||||||
|
|
||||||
// deselect line tool
|
// deselect line tool
|
||||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||||
@ -259,66 +260,88 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([-79.26, 95.04], %)
|
|> startProfileAt([-79.26, 95.04], %)
|
||||||
|> line(end = [112.54, 127.64], tag = $seg02)
|
|> line(end = [112.54, 127.64], tag = $seg02)
|
||||||
|> line(end = [170.36, -121.61], tag = $seg01)
|
|> line(end = [170.36, -121.61], tag = $seg01)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(sketch001, length = 50)
|
extrude001 = extrude(sketch001, length = 50)
|
||||||
sketch005 = startSketchOn(extrude001, 'END')
|
sketch005 = startSketchOn(extrude001, 'END')
|
||||||
|> startProfileAt([23.24, 136.52], %)
|
|> startProfileAt([23.24, 136.52], %)
|
||||||
|> line(end = [-8.44, 36.61])
|
|> line(end = [-8.44, 36.61])
|
||||||
|> line(end = [49.4, 2.05])
|
|> line(end = [49.4, 2.05])
|
||||||
|> line(end = [29.69, -46.95])
|
|> line(end = [29.69, -46.95])
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch003 = startSketchOn(extrude001, seg01)
|
sketch003 = startSketchOn(extrude001, seg01)
|
||||||
|> startProfileAt([21.23, 17.81], %)
|
|> startProfileAt([21.23, 17.81], %)
|
||||||
|> line(end = [51.97, 21.32])
|
|> line(end = [51.97, 21.32])
|
||||||
|> line(end = [4.07, -22.75])
|
|> line(end = [4.07, -22.75])
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch002 = startSketchOn(extrude001, seg02)
|
sketch002 = startSketchOn(extrude001, seg02)
|
||||||
|> startProfileAt([-100.54, 16.99], %)
|
|> startProfileAt([-100.54, 16.99], %)
|
||||||
|> line(end = [0, 20.03])
|
|> line(end = [0, 20.03])
|
||||||
|> line(end = [62.61, 0], tag = $seg03)
|
|> line(end = [62.61, 0], tag = $seg03)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude002 = extrude(sketch002, length = 50)
|
extrude002 = extrude(sketch002, length = 50)
|
||||||
sketch004 = startSketchOn(extrude002, seg03)
|
sketch004 = startSketchOn(extrude002, seg03)
|
||||||
|> startProfileAt([57.07, 134.77], %)
|
|> startProfileAt([57.07, 134.77], %)
|
||||||
|> line(end = [-4.72, 22.84])
|
|> line(end = [-4.72, 22.84])
|
||||||
|> line(end = [28.8, 6.71])
|
|> line(end = [28.8, 6.71])
|
||||||
|> line(end = [9.19, -25.33])
|
|> line(end = [9.19, -25.33])
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude003 = extrude(sketch004, length = 20)
|
extrude003 = extrude(sketch004, length = 20)
|
||||||
pipeLength = 40
|
pipeLength = 40
|
||||||
pipeSmallDia = 10
|
pipeSmallDia = 10
|
||||||
pipeLargeDia = 20
|
pipeLargeDia = 20
|
||||||
thickness = 0.5
|
thickness = 0.5
|
||||||
part009 = startSketchOn('XY')
|
part009 = startSketchOn('XY')
|
||||||
|> startProfileAt([pipeLargeDia - (thickness / 2), 38], %)
|
|> startProfileAt([pipeLargeDia - (thickness / 2), 38], %)
|
||||||
|> line(end = [thickness, 0])
|
|> line(end = [thickness, 0])
|
||||||
|> line(end = [0, -1])
|
|> line(end = [0, -1])
|
||||||
|> angledLineToX({
|
|> angledLineToX({
|
||||||
angle = 60,
|
angle = 60,
|
||||||
to = pipeSmallDia + thickness
|
to = pipeSmallDia + thickness
|
||||||
}, %)
|
}, %)
|
||||||
|> line(end = [0, -pipeLength])
|
|> line(end = [0, -pipeLength])
|
||||||
|> angledLineToX({
|
|> angledLineToX({
|
||||||
angle = -60,
|
angle = -60,
|
||||||
to = pipeLargeDia + thickness
|
to = pipeLargeDia + thickness
|
||||||
}, %)
|
}, %)
|
||||||
|> line(end = [0, -1])
|
|> line(end = [0, -1])
|
||||||
|> line(end = [-thickness, 0])
|
|> line(end = [-thickness, 0])
|
||||||
|> line(end = [0, 1])
|
|> line(end = [0, 1])
|
||||||
|> angledLineToX({ angle = 120, to = pipeSmallDia }, %)
|
|> angledLineToX({ angle = 120, to = pipeSmallDia }, %)
|
||||||
|> line(end = [0, pipeLength])
|
|> line(end = [0, pipeLength])
|
||||||
|> angledLineToX({ angle = 60, to = pipeLargeDia }, %)
|
|> angledLineToX({ angle = 60, to = pipeLargeDia }, %)
|
||||||
|> close()
|
|> close()
|
||||||
rev = revolve({ axis: 'y' }, part009)
|
rev = revolve({ axis = 'y' }, part009)
|
||||||
`
|
sketch006 = startSketchOn('XY')
|
||||||
|
profile001 = circle({
|
||||||
|
center = [42.91, -70.42],
|
||||||
|
radius = 17.96
|
||||||
|
}, sketch006)
|
||||||
|
profile002 = startProfileAt([86.92, -63.81], sketch006)
|
||||||
|
|> angledLine([0, 63.81], %, $rectangleSegmentA001)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001) - 90,
|
||||||
|
17.05
|
||||||
|
], %)
|
||||||
|
|> angledLine([
|
||||||
|
segAng(rectangleSegmentA001),
|
||||||
|
-segLen(rectangleSegmentA001)
|
||||||
|
], %)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
profile003 = startProfileAt([40.16, -120.48], sketch006)
|
||||||
|
|> line(end = [26.95, 24.21])
|
||||||
|
|> line(end = [20.91, -28.61])
|
||||||
|
|> line(end = [32.46, 18.71])
|
||||||
|
|
||||||
|
`
|
||||||
)
|
)
|
||||||
}, KCL_DEFAULT_LENGTH)
|
}, KCL_DEFAULT_LENGTH)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
@ -347,9 +370,10 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
})
|
})
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
const revolve = { x: 646, y: 248 }
|
const revolve = { x: 635, y: 253 }
|
||||||
const parentExtrude = { x: 915, y: 133 }
|
const parentExtrude = { x: 915, y: 133 }
|
||||||
const solid2d = { x: 770, y: 167 }
|
const solid2d = { x: 770, y: 167 }
|
||||||
|
const individualProfile = { x: 694, y: 432 }
|
||||||
|
|
||||||
// DELETE REVOLVE
|
// DELETE REVOLVE
|
||||||
await page.mouse.click(revolve.x, revolve.y)
|
await page.mouse.click(revolve.x, revolve.y)
|
||||||
@ -366,43 +390,47 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
`rev = revolve({ axis: 'y' }, part009)`
|
`rev = revolve({ axis: 'y' }, part009)`
|
||||||
)
|
)
|
||||||
|
|
||||||
// DELETE PARENT EXTRUDE
|
// FIXME (commented section below), this test would select a wall that had a sketch on it, and delete the underlying extrude
|
||||||
await page.mouse.click(parentExtrude.x, parentExtrude.y)
|
// and replace the sketch on face with a hard coded custom plane, but since there was a sketch on that plane maybe it
|
||||||
await page.waitForTimeout(100)
|
// should have delete the sketch? it's broken atm, but not sure if worth fixing since desired behaviour is a little
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(
|
// vague
|
||||||
'|> line(end = [170.36, -121.61], tag = $seg01)'
|
// // DELETE PARENT EXTRUDE
|
||||||
)
|
// await page.mouse.click(parentExtrude.x, parentExtrude.y)
|
||||||
await u.clearCommandLogs()
|
// await page.waitForTimeout(100)
|
||||||
await page.keyboard.press('Backspace')
|
// await expect(page.locator('.cm-activeLine')).toHaveText(
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
// '|> line(end = [170.36, -121.61], tag = $seg01)'
|
||||||
await page.waitForTimeout(200)
|
// )
|
||||||
await expect(u.codeLocator).not.toContainText(
|
// await u.clearCommandLogs()
|
||||||
`extrude001 = extrude(sketch001, length = 50)`
|
// await page.keyboard.press('Backspace')
|
||||||
)
|
// await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
||||||
await expect(u.codeLocator).toContainText(`sketch005 = startSketchOn({
|
// await page.waitForTimeout(200)
|
||||||
plane = {
|
// await expect(u.codeLocator).not.toContainText(
|
||||||
origin = { x = 0, y = -50, z = 0 },
|
// `extrude001 = extrude(sketch001, length = 50)`
|
||||||
xAxis = { x = 1, y = 0, z = 0 },
|
// )
|
||||||
yAxis = { x = 0, y = 0, z = 1 },
|
// await expect(u.codeLocator).toContainText(`sketch005 = startSketchOn({
|
||||||
zAxis = { x = 0, y = -1, z = 0 }
|
// plane = {
|
||||||
}
|
// origin = { x = 0, y = -50, z = 0 },
|
||||||
})`)
|
// xAxis = { x = 1, y = 0, z = 0 },
|
||||||
await expect(u.codeLocator).toContainText(`sketch003 = startSketchOn({
|
// yAxis = { x = 0, y = 0, z = 1 },
|
||||||
plane = {
|
// zAxis = { x = 0, y = -1, z = 0 }
|
||||||
origin = { x = 116.53, y = 0, z = 163.25 },
|
// }
|
||||||
xAxis = { x = -0.81, y = 0, z = 0.58 },
|
// })`)
|
||||||
yAxis = { x = 0, y = -1, z = 0 },
|
// await expect(u.codeLocator).toContainText(`sketch003 = startSketchOn({
|
||||||
zAxis = { x = 0.58, y = 0, z = 0.81 }
|
// plane = {
|
||||||
}
|
// origin = { x = 116.53, y = 0, z = 163.25 },
|
||||||
})`)
|
// xAxis = { x = -0.81, y = 0, z = 0.58 },
|
||||||
await expect(u.codeLocator).toContainText(`sketch002 = startSketchOn({
|
// yAxis = { x = 0, y = -1, z = 0 },
|
||||||
plane = {
|
// zAxis = { x = 0.58, y = 0, z = 0.81 }
|
||||||
origin = { x = -91.74, y = 0, z = 80.89 },
|
// }
|
||||||
xAxis = { x = -0.66, y = 0, z = -0.75 },
|
// })`)
|
||||||
yAxis = { x = 0, y = -1, z = 0 },
|
// await expect(u.codeLocator).toContainText(`sketch002 = startSketchOn({
|
||||||
zAxis = { x = -0.75, y = 0, z = 0.66 }
|
// plane = {
|
||||||
}
|
// origin = { x = -91.74, y = 0, z = 80.89 },
|
||||||
})`)
|
// xAxis = { x = -0.66, y = 0, z = -0.75 },
|
||||||
|
// yAxis = { x = 0, y = -1, z = 0 },
|
||||||
|
// zAxis = { x = -0.75, y = 0, z = 0.66 }
|
||||||
|
// }
|
||||||
|
// })`)
|
||||||
|
|
||||||
// DELETE SOLID 2D
|
// DELETE SOLID 2D
|
||||||
await page.mouse.click(solid2d.x, solid2d.y)
|
await page.mouse.click(solid2d.x, solid2d.y)
|
||||||
@ -415,16 +443,29 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await expect(u.codeLocator).not.toContainText(`sketch005 = startSketchOn({`)
|
await expect(u.codeLocator).not.toContainText(`sketch005 = startSketchOn({`)
|
||||||
|
|
||||||
|
// Delete a single profile
|
||||||
|
await page.mouse.click(individualProfile.x, individualProfile.y)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
const codeToBeDeletedSnippet =
|
||||||
|
'profile003 = startProfileAt([40.16, -120.48], sketch006)'
|
||||||
|
await expect(page.locator('.cm-activeLine')).toHaveText(
|
||||||
|
' |> line(end = [20.91, -28.61])'
|
||||||
|
)
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await page.keyboard.press('Backspace')
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
await expect(u.codeLocator).not.toContainText(codeToBeDeletedSnippet)
|
||||||
})
|
})
|
||||||
test("Deleting solid that the AST mod can't handle results in a toast message", async ({
|
test.fixme(
|
||||||
page,
|
"Deleting solid that the AST mod can't handle results in a toast message",
|
||||||
homePage,
|
async ({ page, homePage }) => {
|
||||||
}) => {
|
const u = await getUtils(page)
|
||||||
const u = await getUtils(page)
|
await page.addInitScript(async () => {
|
||||||
await page.addInitScript(async () => {
|
localStorage.setItem(
|
||||||
localStorage.setItem(
|
'persistCode',
|
||||||
'persistCode',
|
`sketch001 = startSketchOn('XZ')
|
||||||
`sketch001 = startSketchOn('XZ')
|
|
||||||
|> startProfileAt([-79.26, 95.04], %)
|
|> startProfileAt([-79.26, 95.04], %)
|
||||||
|> line(end = [112.54, 127.64], tag = $seg02)
|
|> line(end = [112.54, 127.64], tag = $seg02)
|
||||||
|> line(end = [170.36, -121.61], tag = $seg01)
|
|> line(end = [170.36, -121.61], tag = $seg01)
|
||||||
@ -439,48 +480,49 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
`
|
`
|
||||||
|
)
|
||||||
|
}, KCL_DEFAULT_LENGTH)
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await u.sendCustomCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_look_at',
|
||||||
|
vantage: { x: 1139.49, y: -7053, z: 8597.31 },
|
||||||
|
center: { x: -2206.68, y: -1298.36, z: 60 },
|
||||||
|
up: { x: 0, y: 0, z: 1 },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.sendCustomCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
// attempt delete
|
||||||
|
await page.mouse.click(930, 139)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await expect(page.locator('.cm-activeLine')).toHaveText(
|
||||||
|
'|> line(end = [170.36, -121.61], tag = $seg01)'
|
||||||
)
|
)
|
||||||
}, KCL_DEFAULT_LENGTH)
|
await u.clearCommandLogs()
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.keyboard.press('Backspace')
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await expect(page.getByText('Unable to delete selection')).toBeVisible()
|
||||||
|
}
|
||||||
await u.openDebugPanel()
|
)
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
await u.openAndClearDebugPanel()
|
|
||||||
await u.sendCustomCmd({
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_look_at',
|
|
||||||
vantage: { x: 1139.49, y: -7053, z: 8597.31 },
|
|
||||||
center: { x: -2206.68, y: -1298.36, z: 60 },
|
|
||||||
up: { x: 0, y: 0, z: 1 },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await u.sendCustomCmd({
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_get_settings',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
|
|
||||||
// attempt delete
|
|
||||||
await page.mouse.click(930, 139)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(
|
|
||||||
'|> line(end = [170.36, -121.61], tag = $seg01)'
|
|
||||||
)
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await page.keyboard.press('Backspace')
|
|
||||||
|
|
||||||
await expect(page.getByText('Unable to delete selection')).toBeVisible()
|
|
||||||
})
|
|
||||||
test('Hovering over 3d features highlights code, clicking puts the cursor in the right place and sends selection id to engine', async ({
|
test('Hovering over 3d features highlights code, clicking puts the cursor in the right place and sends selection id to engine', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
@ -1216,12 +1258,15 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
|
|
||||||
await page.waitForTimeout(600)
|
await page.waitForTimeout(600)
|
||||||
|
|
||||||
|
const firstClickCoords = { x: 650, y: 200 } as const
|
||||||
// Place a point because the line tool will exit if no points are pressed
|
// Place a point because the line tool will exit if no points are pressed
|
||||||
await page.mouse.click(650, 200)
|
await page.mouse.click(firstClickCoords.x, firstClickCoords.y)
|
||||||
await page.waitForTimeout(600)
|
await page.waitForTimeout(600)
|
||||||
|
|
||||||
// Code before exiting the tool
|
// Code before exiting the tool
|
||||||
let previousCodeContent = await page.locator('.cm-content').innerText()
|
let previousCodeContent = (
|
||||||
|
await page.locator('.cm-content').innerText()
|
||||||
|
).replace(/\s+/g, '')
|
||||||
|
|
||||||
// deselect the line tool by clicking it
|
// deselect the line tool by clicking it
|
||||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||||
@ -1233,14 +1278,23 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
|||||||
await page.mouse.click(750, 200)
|
await page.mouse.click(750, 200)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
// expect no change
|
await expect
|
||||||
await expect(page.locator('.cm-content')).toHaveText(previousCodeContent)
|
.poll(async () => {
|
||||||
|
let str = await page.locator('.cm-content').innerText()
|
||||||
|
str = str.replace(/\s+/g, '')
|
||||||
|
return str
|
||||||
|
})
|
||||||
|
.toBe(previousCodeContent)
|
||||||
|
|
||||||
// select line tool again
|
// select line tool again
|
||||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
// Click to continue profile
|
||||||
|
await page.mouse.click(firstClickCoords.x, firstClickCoords.y)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
// line tool should work as expected again
|
// line tool should work as expected again
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(
|
await expect(page.locator('.cm-content')).not.toHaveText(
|
||||||
|
@ -209,8 +209,13 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
|||||||
// Draw a line
|
// Draw a line
|
||||||
await page.mouse.move(700, 200, { steps: 5 })
|
await page.mouse.move(700, 200, { steps: 5 })
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
await page.mouse.move(800, 250, { steps: 5 })
|
|
||||||
await page.mouse.click(800, 250)
|
const secondMousePosition = { x: 800, y: 250 }
|
||||||
|
|
||||||
|
await page.mouse.move(secondMousePosition.x, secondMousePosition.y, {
|
||||||
|
steps: 5,
|
||||||
|
})
|
||||||
|
await page.mouse.click(secondMousePosition.x, secondMousePosition.y)
|
||||||
// Unequip line tool
|
// Unequip line tool
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
// Make sure we didn't pop out of sketch mode.
|
// Make sure we didn't pop out of sketch mode.
|
||||||
@ -219,11 +224,23 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
|||||||
// Equip arc tool
|
// Equip arc tool
|
||||||
await page.keyboard.press('a')
|
await page.keyboard.press('a')
|
||||||
await expect(arcButton).toHaveAttribute('aria-pressed', 'true')
|
await expect(arcButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
|
// click in the same position again to continue the profile
|
||||||
|
await page.mouse.move(secondMousePosition.x, secondMousePosition.y, {
|
||||||
|
steps: 5,
|
||||||
|
})
|
||||||
|
await page.mouse.click(secondMousePosition.x, secondMousePosition.y)
|
||||||
|
|
||||||
await page.mouse.move(1000, 100, { steps: 5 })
|
await page.mouse.move(1000, 100, { steps: 5 })
|
||||||
await page.mouse.click(1000, 100)
|
await page.mouse.click(1000, 100)
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
await page.keyboard.press('l')
|
await expect(arcButton).toHaveAttribute('aria-pressed', 'false')
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
await expect
|
||||||
|
.poll(async () => {
|
||||||
|
await page.keyboard.press('l')
|
||||||
|
return lineButton.getAttribute('aria-pressed')
|
||||||
|
})
|
||||||
|
.toBe('true')
|
||||||
|
|
||||||
// Do not close the sketch.
|
// Do not close the sketch.
|
||||||
// On close it will exit sketch mode.
|
// On close it will exit sketch mode.
|
||||||
@ -519,9 +536,9 @@ extrude001 = extrude(sketch001, length = 5 + 7)`
|
|||||||
|
|
||||||
await expect.poll(u.normalisedEditorCode).toContain(
|
await expect.poll(u.normalisedEditorCode).toContain(
|
||||||
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
|
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
|
||||||
|> startProfileAt([-12.94, 6.6], %)
|
profile001 = startProfileAt([-12.34, 12.34], sketch002)
|
||||||
|> line(end = [2.45, -0.2])
|
|> line(end = [12.34, -12.34])
|
||||||
|> line(end = [-2.6, -1.25])
|
|> line(end = [-12.34, -12.34])
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
`)
|
`)
|
||||||
@ -537,9 +554,8 @@ extrude001 = extrude(sketch001, length = 5 + 7)`
|
|||||||
await page.getByText('startProfileAt([-12').click()
|
await page.getByText('startProfileAt([-12').click()
|
||||||
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
|
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
await page.waitForTimeout(400)
|
await page.waitForTimeout(500)
|
||||||
await page.waitForTimeout(150)
|
await page.setViewportSize({ width: 1200, height: 1200 })
|
||||||
await page.setBodyDimensions({ width: 1200, height: 1200 })
|
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await u.updateCamPosition([452, -152, 1166])
|
await u.updateCamPosition([452, -152, 1166])
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
@ -16,8 +16,7 @@ mac:
|
|||||||
arch:
|
arch:
|
||||||
- x64
|
- x64
|
||||||
- arm64
|
- arm64
|
||||||
notarize:
|
notarize: true
|
||||||
teamId: 92H8YB3B95
|
|
||||||
fileAssociations:
|
fileAssociations:
|
||||||
- ext: kcl
|
- ext: kcl
|
||||||
name: kcl
|
name: kcl
|
||||||
@ -32,10 +31,11 @@ win:
|
|||||||
arch:
|
arch:
|
||||||
- x64
|
- x64
|
||||||
- arm64
|
- arm64
|
||||||
signingHashAlgorithms:
|
signtoolOptions:
|
||||||
- sha256
|
sign: "./scripts/sign-win.js"
|
||||||
sign: "./scripts/sign-win.js"
|
signingHashAlgorithms:
|
||||||
publisherName: "KittyCAD Inc" # needs to be exactly like on Digicert
|
- sha256
|
||||||
|
publisherName: "KittyCAD Inc" # needs to be exactly like on Digicert
|
||||||
icon: "assets/icon.ico"
|
icon: "assets/icon.ico"
|
||||||
fileAssociations:
|
fileAssociations:
|
||||||
- ext: kcl
|
- ext: kcl
|
||||||
|