Compare commits
11 Commits
kurt-rever
...
paultag/ma
Author | SHA1 | Date | |
---|---|---|---|
eea823e0bc | |||
a1b875062f | |||
4e0dd12f5a | |||
bcf2572739 | |||
074c285e04 | |||
0924dd4f60 | |||
6b7f200564 | |||
1a7339fb70 | |||
c1a450b15e | |||
d7bc92afd9 | |||
11dfd87240 |
2
.github/ci-cd-scripts/playwright-electron.sh
vendored
@ -19,7 +19,7 @@ if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||
fi
|
||||
|
||||
retry=1
|
||||
max_retrys=2
|
||||
max_retrys=4
|
||||
|
||||
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
|
||||
while [[ $retry -le $max_retrys ]]; do
|
||||
|
8
.github/workflows/e2e-tests.yml
vendored
@ -142,6 +142,7 @@ jobs:
|
||||
with:
|
||||
name: playwright-report-${{ matrix.os }}-snapshot-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||
path: playwright-report/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
- name: Clean up test-results
|
||||
@ -177,6 +178,7 @@ jobs:
|
||||
with:
|
||||
name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||
path: playwright-report/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
- uses: actions/download-artifact@v4
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
@ -207,6 +209,7 @@ jobs:
|
||||
with:
|
||||
name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||
path: test-results/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
- uses: actions/upload-artifact@v4
|
||||
@ -214,6 +217,7 @@ jobs:
|
||||
with:
|
||||
name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||
path: playwright-report/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
|
||||
@ -313,7 +317,7 @@ jobs:
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: test-results-${{ matrix.os }}-${{ github.sha }}
|
||||
name: test-results-electron-${{ matrix.os }}-${{ github.sha }}
|
||||
path: test-results/
|
||||
- name: Run electron tests (with retries)
|
||||
id: retry
|
||||
@ -339,6 +343,7 @@ jobs:
|
||||
with:
|
||||
name: test-results-electron-${{ matrix.os }}-${{ github.sha }}
|
||||
path: test-results/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
- uses: actions/upload-artifact@v4
|
||||
@ -346,5 +351,6 @@ jobs:
|
||||
with:
|
||||
name: playwright-report-electron-${{ matrix.os }}-${{ github.sha }}
|
||||
path: playwright-report/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
|
@ -1115,6 +1115,102 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
).toHaveAttribute('aria-pressed', 'true')
|
||||
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||
})
|
||||
|
||||
test('Can sketch on face when user defined function was used in the sketch', async ({
|
||||
page,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Checking for a regression that performs a sketch when a user defined function
|
||||
// is declared at the top of the file and used in the sketch that is being drawn on.
|
||||
// fn in2mm is declared at the top of the file and used rail which does a an extrusion with the function.
|
||||
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`fn in2mm = (inches) => {
|
||||
return inches * 25.4
|
||||
}
|
||||
|
||||
const railTop = in2mm(.748)
|
||||
const railSide = in2mm(.024)
|
||||
const railBaseWidth = in2mm(.612)
|
||||
const railWideWidth = in2mm(.835)
|
||||
const railBaseLength = in2mm(.200)
|
||||
const railClampable = in2mm(.200)
|
||||
|
||||
const rail = startSketchOn('XZ')
|
||||
|> startProfileAt([
|
||||
-railTop / 2,
|
||||
railClampable + railBaseLength
|
||||
], %)
|
||||
|> lineTo([
|
||||
railTop / 2,
|
||||
railClampable + railBaseLength
|
||||
], %)
|
||||
|> lineTo([
|
||||
railWideWidth / 2,
|
||||
railClampable / 2 + railBaseLength
|
||||
], %, $seg01)
|
||||
|> lineTo([railTop / 2, railBaseLength], %)
|
||||
|> lineTo([railBaseWidth / 2, railBaseLength], %)
|
||||
|> lineTo([railBaseWidth / 2, 0], %)
|
||||
|> lineTo([-railBaseWidth / 2, 0], %)
|
||||
|> lineTo([-railBaseWidth / 2, railBaseLength], %)
|
||||
|> lineTo([-railTop / 2, railBaseLength], %)
|
||||
|> lineTo([
|
||||
-railWideWidth / 2,
|
||||
railClampable / 2 + railBaseLength
|
||||
], %)
|
||||
|> lineTo([
|
||||
-railTop / 2,
|
||||
railClampable + railBaseLength
|
||||
], %)
|
||||
|> close(%)
|
||||
|> extrude(in2mm(2), %)`
|
||||
)
|
||||
})
|
||||
|
||||
const center = { x: 600, y: 250 }
|
||||
const rectangleSize = 20
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
// Start a sketch
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
|
||||
// Click the top face of this rail
|
||||
await page.mouse.click(center.x, center.y)
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
// Draw a rectangle
|
||||
// top left
|
||||
await page.mouse.click(center.x - rectangleSize, center.y - rectangleSize)
|
||||
await page.waitForTimeout(250)
|
||||
// top right
|
||||
await page.mouse.click(center.x + rectangleSize, center.y - rectangleSize)
|
||||
await page.waitForTimeout(250)
|
||||
|
||||
// bottom right
|
||||
await page.mouse.click(center.x + rectangleSize, center.y + rectangleSize)
|
||||
await page.waitForTimeout(250)
|
||||
|
||||
// bottom left
|
||||
await page.mouse.click(center.x - rectangleSize, center.y + rectangleSize)
|
||||
await page.waitForTimeout(250)
|
||||
|
||||
// top left
|
||||
await page.mouse.click(center.x - rectangleSize, center.y - rectangleSize)
|
||||
await page.waitForTimeout(250)
|
||||
|
||||
// exit sketch
|
||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||
|
||||
// Check execution is done
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.closeDebugPanel()
|
||||
})
|
||||
})
|
||||
|
||||
test2.describe('Sketch mode should be toleratant to syntax errors', () => {
|
||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 65 KiB |
@ -113,12 +113,21 @@
|
||||
],
|
||||
"description": "Maximum part size that can be manufactured by this device. This may be some sort of theoretical upper bound, getting close to this limit seems like maybe a bad idea.\n\nThis may be `None` if the maximum size is not knowable by the Machine API.\n\nWhat \"close\" means is up to you!",
|
||||
"nullable": true
|
||||
},
|
||||
"state": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MachineState"
|
||||
}
|
||||
],
|
||||
"description": "Status of the printer -- be it printing, idle, or unreachable. This may dictate if a machine is capable of taking a new job."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"machine_type",
|
||||
"make_model"
|
||||
"make_model",
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
@ -143,6 +152,67 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"MachineState": {
|
||||
"description": "Current state of the machine -- be it printing, idle or offline. This can be used to determine if a printer is in the correct state to take a new job.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "If a print state can not be resolved at this time, an Unknown may be returned.",
|
||||
"enum": [
|
||||
"Unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Idle, and ready for another job.",
|
||||
"enum": [
|
||||
"Idle"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Running a job -- 3D printing or CNC-ing a part.",
|
||||
"enum": [
|
||||
"Running"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Machine is currently offline or unreachable.",
|
||||
"enum": [
|
||||
"Offline"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Job is underway but halted, waiting for some action to take place.",
|
||||
"enum": [
|
||||
"Paused"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Job is finished, but waiting manual action to move back to Idle.",
|
||||
"enum": [
|
||||
"Complete"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"description": "The printer has failed and is in an unknown state that may require manual attention to resolve. The inner value is a human readable description of what specifically has failed.",
|
||||
"properties": {
|
||||
"Failed": {
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Failed"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"MachineType": {
|
||||
"description": "Specific technique by which this Machine takes a design, and produces a real-world 3D object.",
|
||||
"oneOf": [
|
||||
|
@ -2,6 +2,7 @@ import { styleTags, tags as t } from '@lezer/highlight'
|
||||
|
||||
export const kclHighlight = styleTags({
|
||||
'fn var let const': t.definitionKeyword,
|
||||
'if else': t.controlKeyword,
|
||||
return: t.controlKeyword,
|
||||
'true false': t.bool,
|
||||
nil: t.null,
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
statement[@isGroup=Statement] {
|
||||
FunctionDeclaration { kw<"fn"> VariableDefinition Equals ParamList Arrow Body } |
|
||||
VariableDeclaration { (kw<"var"> | kw<"let"> | kw<"const">) VariableDefinition Equals expression } |
|
||||
VariableDeclaration { (kw<"var"> | kw<"let"> | kw<"const">)? VariableDefinition Equals expression } |
|
||||
ReturnStatement { kw<"return"> expression } |
|
||||
ExpressionStatement { expression }
|
||||
}
|
||||
@ -40,6 +40,7 @@ expression[@isGroup=Expression] {
|
||||
} |
|
||||
UnaryExpression { UnaryOp expression } |
|
||||
ParenthesizedExpression { "(" expression ")" } |
|
||||
IfExpression { kw<"if"> expression Body kw<"else"> Body } |
|
||||
CallExpression { expression !call ArgumentList } |
|
||||
ArrayExpression { "[" commaSep<expression | IntegerRange { expression !range ".." expression }> "]" } |
|
||||
ObjectExpression { "{" commaSep<ObjectProperty> "}" } |
|
||||
|
13
src/lib/machine-api.d.ts
vendored
@ -126,6 +126,8 @@ export interface components {
|
||||
*
|
||||
* What "close" means is up to you! */
|
||||
max_part_volume?: components['schemas']['Volume'] | null
|
||||
/** @description Status of the printer -- be it printing, idle, or unreachable. This may dictate if a machine is capable of taking a new job. */
|
||||
state: components['schemas']['MachineState']
|
||||
}
|
||||
/** @description Information regarding the make/model of a discovered endpoint. */
|
||||
MachineMakeModel: {
|
||||
@ -136,6 +138,17 @@ export interface components {
|
||||
/** @description The unique serial number of the connected Machine. */
|
||||
serial?: string | null
|
||||
}
|
||||
/** @description Current state of the machine -- be it printing, idle or offline. This can be used to determine if a printer is in the correct state to take a new job. */
|
||||
MachineState:
|
||||
| 'Unknown'
|
||||
| 'Idle'
|
||||
| 'Running'
|
||||
| 'Offline'
|
||||
| 'Paused'
|
||||
| 'Complete'
|
||||
| {
|
||||
Failed: string | null
|
||||
}
|
||||
/** @description Specific technique by which this Machine takes a design, and produces a real-world 3D object. */
|
||||
MachineType: 'Stereolithography' | 'FusedDeposition' | 'Cnc'
|
||||
/** @description The response from the `/ping` endpoint. */
|
||||
|