Compare commits
5 Commits
pierremtb/
...
v0.55.0
Author | SHA1 | Date | |
---|---|---|---|
01c6fd53fa | |||
f8306c0275 | |||
900ef9e18d | |||
a46186573c | |||
90f6c1bb04 |
5
.github/workflows/e2e-tests.yml
vendored
5
.github/workflows/e2e-tests.yml
vendored
@ -285,8 +285,7 @@ jobs:
|
|||||||
# TODO: enable namespace-profile-windows-latest once available
|
# TODO: enable namespace-profile-windows-latest once available
|
||||||
os:
|
os:
|
||||||
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
|
||||||
# TODO: renable this when macoOS runner seem more stable
|
- namespace-profile-macos-8-cores
|
||||||
# - namespace-profile-macos-6-cores
|
|
||||||
- windows-latest-8-cores
|
- windows-latest-8-cores
|
||||||
shardIndex: [1, 2, 3, 4]
|
shardIndex: [1, 2, 3, 4]
|
||||||
shardTotal: [4]
|
shardTotal: [4]
|
||||||
@ -296,7 +295,7 @@ jobs:
|
|||||||
isScheduled:
|
isScheduled:
|
||||||
- ${{ github.event_name == 'schedule' }}
|
- ${{ github.event_name == 'schedule' }}
|
||||||
exclude:
|
exclude:
|
||||||
- os: namespace-profile-macos-6-cores
|
- os: namespace-profile-macos-8-cores
|
||||||
isScheduled: true
|
isScheduled: true
|
||||||
- os: windows-latest-8-cores
|
- os: windows-latest-8-cores
|
||||||
isScheduled: true
|
isScheduled: true
|
||||||
|
@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin value.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
profileStart(sketch: Sketch): [number]
|
profileStart(profile: Sketch): [number]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ profileStart(sketch: Sketch): [number]
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
|
| `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin's 'x' value.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
profileStartX(sketch: Sketch): number
|
profileStartX(profile: Sketch): number
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ profileStartX(sketch: Sketch): number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
|
| `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin's 'y' value.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
profileStartY(sketch: Sketch): number
|
profileStartY(profile: Sketch): number
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ profileStartY(sketch: Sketch): number
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
|
| `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -237227,10 +237227,10 @@
|
|||||||
"summary": "Extract the provided 2-dimensional sketch's profile's origin value.",
|
"summary": "Extract the provided 2-dimensional sketch's profile's origin value.",
|
||||||
"description": "",
|
"description": "",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"keywordArguments": false,
|
"keywordArguments": true,
|
||||||
"args": [
|
"args": [
|
||||||
{
|
{
|
||||||
"name": "sketch",
|
"name": "profile",
|
||||||
"type": "Sketch",
|
"type": "Sketch",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
@ -238899,7 +238899,8 @@
|
|||||||
},
|
},
|
||||||
"required": true,
|
"required": true,
|
||||||
"includeInSnippet": true,
|
"includeInSnippet": true,
|
||||||
"labelRequired": true
|
"description": "Profile whose start is being used",
|
||||||
|
"labelRequired": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"returnValue": {
|
"returnValue": {
|
||||||
@ -238931,10 +238932,10 @@
|
|||||||
"summary": "Extract the provided 2-dimensional sketch's profile's origin's 'x' value.",
|
"summary": "Extract the provided 2-dimensional sketch's profile's origin's 'x' value.",
|
||||||
"description": "",
|
"description": "",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"keywordArguments": false,
|
"keywordArguments": true,
|
||||||
"args": [
|
"args": [
|
||||||
{
|
{
|
||||||
"name": "sketch",
|
"name": "profile",
|
||||||
"type": "Sketch",
|
"type": "Sketch",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
@ -240603,7 +240604,8 @@
|
|||||||
},
|
},
|
||||||
"required": true,
|
"required": true,
|
||||||
"includeInSnippet": true,
|
"includeInSnippet": true,
|
||||||
"labelRequired": true
|
"description": "Profile whose start is being used",
|
||||||
|
"labelRequired": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"returnValue": {
|
"returnValue": {
|
||||||
@ -240630,10 +240632,10 @@
|
|||||||
"summary": "Extract the provided 2-dimensional sketch's profile's origin's 'y' value.",
|
"summary": "Extract the provided 2-dimensional sketch's profile's origin's 'y' value.",
|
||||||
"description": "",
|
"description": "",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"keywordArguments": false,
|
"keywordArguments": true,
|
||||||
"args": [
|
"args": [
|
||||||
{
|
{
|
||||||
"name": "sketch",
|
"name": "profile",
|
||||||
"type": "Sketch",
|
"type": "Sketch",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
@ -242302,7 +242304,8 @@
|
|||||||
},
|
},
|
||||||
"required": true,
|
"required": true,
|
||||||
"includeInSnippet": true,
|
"includeInSnippet": true,
|
||||||
"labelRequired": true
|
"description": "Profile whose start is being used",
|
||||||
|
"labelRequired": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"returnValue": {
|
"returnValue": {
|
||||||
|
@ -29,11 +29,11 @@ test.describe('Electron app header tests', () => {
|
|||||||
test(
|
test(
|
||||||
'User settings has correct shortcut',
|
'User settings has correct shortcut',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ page }, testInfo) => {
|
async ({ page, toolbar }, testInfo) => {
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
// Open the user sidebar menu.
|
// Open the user sidebar menu.
|
||||||
await page.getByTestId('user-sidebar-toggle').click()
|
await toolbar.userSidebarButton.click()
|
||||||
|
|
||||||
// No space after "User settings" since it's textContent.
|
// No space after "User settings" since it's textContent.
|
||||||
const text =
|
const text =
|
||||||
|
53
e2e/playwright/auth.spec.ts
Normal file
53
e2e/playwright/auth.spec.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
|
// test file is for testing auth functionality
|
||||||
|
test.describe('Authentication tests', () => {
|
||||||
|
test(
|
||||||
|
`The user can sign out and back in`,
|
||||||
|
{ tag: ['@electron'] },
|
||||||
|
async ({ page, homePage, signInPage, toolbar, tronApp }) => {
|
||||||
|
if (!tronApp) {
|
||||||
|
fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.projectSection.waitFor()
|
||||||
|
|
||||||
|
await test.step('Click on sign out and expect sign in page', async () => {
|
||||||
|
await toolbar.userSidebarButton.click()
|
||||||
|
await toolbar.signOutButton.click()
|
||||||
|
await expect(signInPage.signInButton).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Click on sign in and cancel, click again and expect different code', async () => {
|
||||||
|
await signInPage.signInButton.click()
|
||||||
|
await expect(signInPage.userCode).toBeVisible()
|
||||||
|
const firstUserCode = await signInPage.userCode.textContent()
|
||||||
|
await signInPage.cancelSignInButton.click()
|
||||||
|
await expect(signInPage.signInButton).toBeVisible()
|
||||||
|
|
||||||
|
await signInPage.signInButton.click()
|
||||||
|
await expect(signInPage.userCode).toBeVisible()
|
||||||
|
const secondUserCode = await signInPage.userCode.textContent()
|
||||||
|
expect(secondUserCode).not.toEqual(firstUserCode)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Press back button and remain on home page', async () => {
|
||||||
|
await page.goBack()
|
||||||
|
await expect(homePage.projectSection).not.toBeVisible()
|
||||||
|
await expect(signInPage.signInButton).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Sign in, activate, and expect home page', async () => {
|
||||||
|
await signInPage.signInButton.click()
|
||||||
|
await expect(signInPage.userCode).toBeVisible()
|
||||||
|
const userCode = await signInPage.userCode.textContent()
|
||||||
|
expect(userCode).not.toBeNull()
|
||||||
|
await signInPage.verifyAndConfirmAuth(userCode!)
|
||||||
|
|
||||||
|
// Longer timeout than usual here for the wait on home page
|
||||||
|
await expect(homePage.projectSection).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
@ -18,6 +18,7 @@ import type { Settings } from '@rust/kcl-lib/bindings/Settings'
|
|||||||
import { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
import { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||||
import { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
import { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
||||||
import { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
import { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
||||||
|
import { SignInPageFixture } from '@e2e/playwright/fixtures/signInPageFixture'
|
||||||
import { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
import { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
import { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ export interface Fixtures {
|
|||||||
toolbar: ToolbarFixture
|
toolbar: ToolbarFixture
|
||||||
scene: SceneFixture
|
scene: SceneFixture
|
||||||
homePage: HomePageFixture
|
homePage: HomePageFixture
|
||||||
|
signInPage: SignInPageFixture
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ElectronZoo {
|
export class ElectronZoo {
|
||||||
@ -387,6 +389,9 @@ const fixturesBasedOnProcessEnvPlatform = {
|
|||||||
homePage: async ({ page }: { page: Page }, use: FnUse) => {
|
homePage: async ({ page }: { page: Page }, use: FnUse) => {
|
||||||
await use(new HomePageFixture(page))
|
await use(new HomePageFixture(page))
|
||||||
},
|
},
|
||||||
|
signInPage: async ({ page }: { page: Page }, use: FnUse) => {
|
||||||
|
await use(new SignInPageFixture(page))
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.PLATFORM === 'web') {
|
if (process.env.PLATFORM === 'web') {
|
||||||
|
48
e2e/playwright/fixtures/signInPageFixture.ts
Normal file
48
e2e/playwright/fixtures/signInPageFixture.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import type { Locator, Page } from '@playwright/test'
|
||||||
|
import { secrets } from '@e2e/playwright/secrets'
|
||||||
|
|
||||||
|
export class SignInPageFixture {
|
||||||
|
public page: Page
|
||||||
|
|
||||||
|
signInButton!: Locator
|
||||||
|
cancelSignInButton!: Locator
|
||||||
|
userCode!: Locator
|
||||||
|
|
||||||
|
apiBaseUrl!: string
|
||||||
|
|
||||||
|
constructor(page: Page) {
|
||||||
|
this.page = page
|
||||||
|
|
||||||
|
this.signInButton = this.page.getByTestId('sign-in-button')
|
||||||
|
this.cancelSignInButton = this.page.getByTestId('cancel-sign-in-button')
|
||||||
|
this.userCode = this.page.getByTestId('sign-in-user-code')
|
||||||
|
|
||||||
|
// TODO: set this thru env var
|
||||||
|
this.apiBaseUrl = 'https://api.dev.zoo.dev'
|
||||||
|
}
|
||||||
|
|
||||||
|
async verifyAndConfirmAuth(userCode: string) {
|
||||||
|
// Device flow: stolen from the tauri days
|
||||||
|
// https://github.com/KittyCAD/modeling-app/blob/d916c7987452e480719004e6d11fd2e595c7d0eb/e2e/tauri/specs/app.spec.ts#L19
|
||||||
|
const headers = {
|
||||||
|
Authorization: `Bearer ${secrets.token}`,
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
const verifyUrl = `${this.apiBaseUrl}/oauth2/device/verify?user_code=${userCode}`
|
||||||
|
console.log(`GET ${verifyUrl}`)
|
||||||
|
const vr = await fetch(verifyUrl, { headers })
|
||||||
|
console.log(vr.status)
|
||||||
|
|
||||||
|
// Device flow: confirm
|
||||||
|
const confirmUrl = `${this.apiBaseUrl}/oauth2/device/confirm`
|
||||||
|
const data = JSON.stringify({ user_code: userCode })
|
||||||
|
console.log(`POST ${confirmUrl} ${data}`)
|
||||||
|
const cr = await fetch(confirmUrl, {
|
||||||
|
headers,
|
||||||
|
method: 'POST',
|
||||||
|
body: data,
|
||||||
|
})
|
||||||
|
console.log(cr.status)
|
||||||
|
}
|
||||||
|
}
|
@ -46,6 +46,9 @@ export class ToolbarFixture {
|
|||||||
gizmo!: Locator
|
gizmo!: Locator
|
||||||
gizmoDisabled!: Locator
|
gizmoDisabled!: Locator
|
||||||
loadButton!: Locator
|
loadButton!: Locator
|
||||||
|
/** User button for the user sidebar menu */
|
||||||
|
userSidebarButton!: Locator
|
||||||
|
signOutButton!: Locator
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page
|
this.page = page
|
||||||
@ -82,6 +85,9 @@ export class ToolbarFixture {
|
|||||||
// element or two different elements can represent these states.
|
// element or two different elements can represent these states.
|
||||||
this.gizmo = page.getByTestId('gizmo')
|
this.gizmo = page.getByTestId('gizmo')
|
||||||
this.gizmoDisabled = page.getByTestId('gizmo-disabled')
|
this.gizmoDisabled = page.getByTestId('gizmo-disabled')
|
||||||
|
|
||||||
|
this.userSidebarButton = page.getByTestId('user-sidebar-toggle')
|
||||||
|
this.signOutButton = page.getByTestId('user-sidebar-sign-out')
|
||||||
}
|
}
|
||||||
|
|
||||||
get logoLink() {
|
get logoLink() {
|
||||||
|
@ -331,6 +331,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
test('Avatar text updates depending on image load success', async ({
|
test('Avatar text updates depending on image load success', async ({
|
||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
|
toolbar,
|
||||||
homePage,
|
homePage,
|
||||||
tronApp,
|
tronApp,
|
||||||
}) => {
|
}) => {
|
||||||
@ -362,7 +363,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
// Test that the text in this step is correct
|
// Test that the text in this step is correct
|
||||||
const avatarLocator = page.getByTestId('user-sidebar-toggle').locator('img')
|
const avatarLocator = toolbar.userSidebarButton.locator('img')
|
||||||
const onboardingOverlayLocator = page
|
const onboardingOverlayLocator = page
|
||||||
.getByTestId('onboarding-content')
|
.getByTestId('onboarding-content')
|
||||||
.locator('div')
|
.locator('div')
|
||||||
@ -404,6 +405,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
test("Avatar text doesn't mention avatar when no avatar", async ({
|
test("Avatar text doesn't mention avatar when no avatar", async ({
|
||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
|
toolbar,
|
||||||
homePage,
|
homePage,
|
||||||
tronApp,
|
tronApp,
|
||||||
}) => {
|
}) => {
|
||||||
@ -435,7 +437,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
// Test that the text in this step is correct
|
// Test that the text in this step is correct
|
||||||
const sidebar = page.getByTestId('user-sidebar-toggle')
|
const sidebar = toolbar.userSidebarButton
|
||||||
const avatar = sidebar.locator('img')
|
const avatar = sidebar.locator('img')
|
||||||
const onboardingOverlayLocator = page
|
const onboardingOverlayLocator = page
|
||||||
.getByTestId('onboarding-content')
|
.getByTestId('onboarding-content')
|
||||||
@ -464,6 +466,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
test('Restarting onboarding on desktop takes one attempt', async ({
|
test('Restarting onboarding on desktop takes one attempt', async ({
|
||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
|
toolbar,
|
||||||
tronApp,
|
tronApp,
|
||||||
}) => {
|
}) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
@ -502,7 +505,7 @@ test('Restarting onboarding on desktop takes one attempt', async ({
|
|||||||
.filter({ hasText: 'Tutorial Project 00' })
|
.filter({ hasText: 'Tutorial Project 00' })
|
||||||
const tutorialModalText = page.getByText('Welcome to Design Studio!')
|
const tutorialModalText = page.getByText('Welcome to Design Studio!')
|
||||||
const tutorialDismissButton = page.getByRole('button', { name: 'Dismiss' })
|
const tutorialDismissButton = page.getByRole('button', { name: 'Dismiss' })
|
||||||
const userMenuButton = page.getByTestId('user-sidebar-toggle')
|
const userMenuButton = toolbar.userSidebarButton
|
||||||
const userMenuSettingsButton = page.getByRole('button', {
|
const userMenuSettingsButton = page.getByRole('button', {
|
||||||
name: 'User settings',
|
name: 'User settings',
|
||||||
})
|
})
|
||||||
|
@ -1962,13 +1962,13 @@ test(
|
|||||||
test(
|
test(
|
||||||
'Settings persist across restarts',
|
'Settings persist across restarts',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ page, scene, cmdBar }, testInfo) => {
|
async ({ page, toolbar }, testInfo) => {
|
||||||
await test.step('We can change a user setting like theme', async () => {
|
await test.step('We can change a user setting like theme', async () => {
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
page.on('console', console.log)
|
page.on('console', console.log)
|
||||||
|
|
||||||
await page.getByTestId('user-sidebar-toggle').click()
|
await toolbar.userSidebarButton.click()
|
||||||
|
|
||||||
await page.getByTestId('user-settings').click()
|
await page.getByTestId('user-settings').click()
|
||||||
|
|
||||||
@ -1995,7 +1995,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'Original project name persist after onboarding',
|
'Original project name persist after onboarding',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ page }, testInfo) => {
|
async ({ page, toolbar }, testInfo) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
@ -2007,7 +2007,7 @@ test(
|
|||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Should go through onboarding', async () => {
|
await test.step('Should go through onboarding', async () => {
|
||||||
await page.getByTestId('user-sidebar-toggle').click()
|
await toolbar.userSidebarButton.click()
|
||||||
await page.getByTestId('user-settings').click()
|
await page.getByTestId('user-settings').click()
|
||||||
await page.getByRole('button', { name: 'Replay Onboarding' }).click()
|
await page.getByRole('button', { name: 'Replay Onboarding' }).click()
|
||||||
|
|
||||||
|
20
rust/Cargo.lock
generated
20
rust/Cargo.lock
generated
@ -1792,7 +1792,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1803,7 +1803,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -1822,7 +1822,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-directory-test-macro"
|
name = "kcl-directory-test-macro"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1831,7 +1831,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-language-server"
|
name = "kcl-language-server"
|
||||||
version = "0.2.62"
|
version = "0.2.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1852,7 +1852,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1872,7 +1872,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.2.62"
|
version = "0.2.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx 0.5.1",
|
"approx 0.5.1",
|
||||||
@ -1943,7 +1943,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-python-bindings"
|
name = "kcl-python-bindings"
|
||||||
version = "0.3.62"
|
version = "0.3.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"kcl-lib",
|
"kcl-lib",
|
||||||
@ -1958,7 +1958,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hyper 0.14.32",
|
"hyper 0.14.32",
|
||||||
@ -1971,7 +1971,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-to-core"
|
name = "kcl-to-core"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1985,7 +1985,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-wasm-lib"
|
name = "kcl-wasm-lib"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bson",
|
"bson",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/KittyCAD/modeling-api"
|
repository = "https://github.com/KittyCAD/modeling-api"
|
||||||
rust-version = "1.76"
|
rust-version = "1.76"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
description = "A tool for generating documentation from Rust derive macros"
|
description = "A tool for generating documentation from Rust derive macros"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-directory-test-macro"
|
name = "kcl-directory-test-macro"
|
||||||
description = "A tool for generating tests from a directory of kcl files"
|
description = "A tool for generating tests from a directory of kcl files"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||||
publish = false
|
publish = false
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "kcl-language-server"
|
name = "kcl-language-server"
|
||||||
description = "A language server for KCL."
|
description = "A language server for KCL."
|
||||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||||
version = "0.2.62"
|
version = "0.2.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language implementation and tools"
|
description = "KittyCAD Language implementation and tools"
|
||||||
version = "0.2.62"
|
version = "0.2.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1820,18 +1820,6 @@ const bracket = startSketchOn(XY)
|
|||||||
parse_execute(ast).await.unwrap();
|
parse_execute(ast).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn test_bad_arg_count_std() {
|
|
||||||
let ast = "startSketchOn(XY)
|
|
||||||
|> startProfileAt([0, 0], %)
|
|
||||||
|> profileStartX()";
|
|
||||||
assert!(parse_execute(ast)
|
|
||||||
.await
|
|
||||||
.unwrap_err()
|
|
||||||
.message()
|
|
||||||
.contains("Expected a sketch argument"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_unary_operator_not_succeeds() {
|
async fn test_unary_operator_not_succeeds() {
|
||||||
let ast = r#"
|
let ast = r#"
|
||||||
|
@ -675,28 +675,6 @@ impl Args {
|
|||||||
Ok((sketches, sketch))
|
Ok((sketches, sketch))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_sketch(&self, exec_state: &mut ExecState) -> Result<Sketch, KclError> {
|
|
||||||
let Some(arg0) = self.args.first() else {
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
|
||||||
message: "Expected a sketch argument".to_owned(),
|
|
||||||
source_ranges: vec![self.source_range],
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
let sarg = arg0
|
|
||||||
.value
|
|
||||||
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
|
|
||||||
.map_err(|_| {
|
|
||||||
KclError::Type(KclErrorDetails {
|
|
||||||
message: format!("Expected a sketch, found {}", arg0.value.human_friendly_type()),
|
|
||||||
source_ranges: vec![self.source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
match sarg {
|
|
||||||
KclValue::Sketch { value } => Ok(*value),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_data<'a, T>(&'a self) -> Result<T, KclError>
|
pub(crate) fn get_data<'a, T>(&'a self) -> Result<T, KclError>
|
||||||
where
|
where
|
||||||
T: FromArgs<'a>,
|
T: FromArgs<'a>,
|
||||||
|
@ -1454,7 +1454,7 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
|
|
||||||
/// Returns the X component of the sketch profile start point.
|
/// Returns the X component of the sketch profile start point.
|
||||||
pub async fn profile_start_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn profile_start_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch: Sketch = args.get_sketch(exec_state)?;
|
let sketch: Sketch = args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::sketch(), exec_state)?;
|
||||||
let ty = sketch.units.into();
|
let ty = sketch.units.into();
|
||||||
let x = inner_profile_start_x(sketch)?;
|
let x = inner_profile_start_x(sketch)?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
|
||||||
@ -1471,15 +1471,20 @@ pub async fn profile_start_x(exec_state: &mut ExecState, args: Args) -> Result<K
|
|||||||
/// |> angledLine(angle = 30, endAbsoluteX = profileStartX(%))
|
/// |> angledLine(angle = 30, endAbsoluteX = profileStartX(%))
|
||||||
/// ```
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "profileStartX"
|
name = "profileStartX",
|
||||||
|
keywords = true,
|
||||||
|
unlabeled_first = true,
|
||||||
|
args = {
|
||||||
|
profile = {docs = "Profile whose start is being used"},
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
pub(crate) fn inner_profile_start_x(sketch: Sketch) -> Result<f64, KclError> {
|
pub(crate) fn inner_profile_start_x(profile: Sketch) -> Result<f64, KclError> {
|
||||||
Ok(sketch.start.to[0])
|
Ok(profile.start.to[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Y component of the sketch profile start point.
|
/// Returns the Y component of the sketch profile start point.
|
||||||
pub async fn profile_start_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn profile_start_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch: Sketch = args.get_sketch(exec_state)?;
|
let sketch: Sketch = args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::sketch(), exec_state)?;
|
||||||
let ty = sketch.units.into();
|
let ty = sketch.units.into();
|
||||||
let x = inner_profile_start_y(sketch)?;
|
let x = inner_profile_start_y(sketch)?;
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
|
||||||
@ -1495,15 +1500,20 @@ pub async fn profile_start_y(exec_state: &mut ExecState, args: Args) -> Result<K
|
|||||||
/// |> angledLine(angle = 30, endAbsoluteY = profileStartY(%))
|
/// |> angledLine(angle = 30, endAbsoluteY = profileStartY(%))
|
||||||
/// ```
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "profileStartY"
|
name = "profileStartY",
|
||||||
|
keywords = true,
|
||||||
|
unlabeled_first = true,
|
||||||
|
args = {
|
||||||
|
profile = {docs = "Profile whose start is being used"},
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
pub(crate) fn inner_profile_start_y(sketch: Sketch) -> Result<f64, KclError> {
|
pub(crate) fn inner_profile_start_y(profile: Sketch) -> Result<f64, KclError> {
|
||||||
Ok(sketch.start.to[1])
|
Ok(profile.start.to[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the sketch profile start point.
|
/// Returns the sketch profile start point.
|
||||||
pub async fn profile_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn profile_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch: Sketch = args.get_sketch(exec_state)?;
|
let sketch: Sketch = args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::sketch(), exec_state)?;
|
||||||
let ty = sketch.units.into();
|
let ty = sketch.units.into();
|
||||||
let point = inner_profile_start(sketch)?;
|
let point = inner_profile_start(sketch)?;
|
||||||
Ok(KclValue::from_point2d(point, ty, args.into()))
|
Ok(KclValue::from_point2d(point, ty, args.into()))
|
||||||
@ -1522,10 +1532,15 @@ pub async fn profile_start(exec_state: &mut ExecState, args: Args) -> Result<Kcl
|
|||||||
/// |> extrude(length = 20)
|
/// |> extrude(length = 20)
|
||||||
/// ```
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "profileStart"
|
name = "profileStart",
|
||||||
|
keywords = true,
|
||||||
|
unlabeled_first = true,
|
||||||
|
args = {
|
||||||
|
profile = {docs = "Profile whose start is being used"},
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
pub(crate) fn inner_profile_start(sketch: Sketch) -> Result<[f64; 2], KclError> {
|
pub(crate) fn inner_profile_start(profile: Sketch) -> Result<[f64; 2], KclError> {
|
||||||
Ok(sketch.start.to)
|
Ok(profile.start.to)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the current sketch.
|
/// Close the current sketch.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-python-bindings"
|
name = "kcl-python-bindings"
|
||||||
version = "0.3.62"
|
version = "0.3.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/kittycad/modeling-app"
|
repository = "https://github.com/kittycad/modeling-app"
|
||||||
exclude = ["tests/*", "files/*", "venv/*"]
|
exclude = ["tests/*", "files/*", "venv/*"]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
description = "A test server for KCL"
|
description = "A test server for KCL"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-to-core"
|
name = "kcl-to-core"
|
||||||
description = "Utility methods to convert kcl to engine core executable tests"
|
description = "Utility methods to convert kcl to engine core executable tests"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-wasm-lib"
|
name = "kcl-wasm-lib"
|
||||||
version = "0.1.62"
|
version = "0.1.63"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
rust-version = "1.83"
|
rust-version = "1.83"
|
||||||
|
@ -1013,13 +1013,18 @@ export class SceneEntities {
|
|||||||
// Snapping logic for the profile start handle
|
// Snapping logic for the profile start handle
|
||||||
if (intersectsProfileStart) {
|
if (intersectsProfileStart) {
|
||||||
const originCoords = createArrayExpression([
|
const originCoords = createArrayExpression([
|
||||||
createCallExpressionStdLib('profileStartX', [
|
createCallExpressionStdLibKw(
|
||||||
|
'profileStartX',
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
]),
|
[]
|
||||||
createCallExpressionStdLib('profileStartY', [
|
),
|
||||||
|
createCallExpressionStdLibKw(
|
||||||
|
'profileStartY',
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
]),
|
[]
|
||||||
|
),
|
||||||
])
|
])
|
||||||
|
|
||||||
modifiedAst = addCallExpressionsToPipe({
|
modifiedAst = addCallExpressionsToPipe({
|
||||||
node: this.kclManager.ast,
|
node: this.kclManager.ast,
|
||||||
variables: this.kclManager.variables,
|
variables: this.kclManager.variables,
|
||||||
@ -2213,13 +2218,18 @@ export class SceneEntities {
|
|||||||
modded = moddedResult.modifiedAst
|
modded = moddedResult.modifiedAst
|
||||||
if (intersectsProfileStart) {
|
if (intersectsProfileStart) {
|
||||||
const originCoords = createArrayExpression([
|
const originCoords = createArrayExpression([
|
||||||
createCallExpressionStdLib('profileStartX', [
|
createCallExpressionStdLibKw(
|
||||||
|
'profileStartX',
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
]),
|
[]
|
||||||
createCallExpressionStdLib('profileStartY', [
|
),
|
||||||
|
createCallExpressionStdLibKw(
|
||||||
|
'profileStartY',
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
]),
|
[]
|
||||||
|
),
|
||||||
])
|
])
|
||||||
|
|
||||||
const arcToCallExp = getNodeFromPath<CallExpression>(
|
const arcToCallExp = getNodeFromPath<CallExpression>(
|
||||||
modded,
|
modded,
|
||||||
mod.pathToNode,
|
mod.pathToNode,
|
||||||
|
@ -15,6 +15,7 @@ export function useAuthNavigation() {
|
|||||||
|
|
||||||
// Subscribe to the auth state of the app and navigate accordingly.
|
// Subscribe to the auth state of the app and navigate accordingly.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log('authState', authState.value)
|
||||||
if (
|
if (
|
||||||
authState.matches('loggedIn') &&
|
authState.matches('loggedIn') &&
|
||||||
location.pathname.includes(PATHS.SIGN_IN)
|
location.pathname.includes(PATHS.SIGN_IN)
|
||||||
@ -26,5 +27,5 @@ export function useAuthNavigation() {
|
|||||||
) {
|
) {
|
||||||
navigate(PATHS.SIGN_IN)
|
navigate(PATHS.SIGN_IN)
|
||||||
}
|
}
|
||||||
}, [authState])
|
}, [authState, location.pathname])
|
||||||
}
|
}
|
||||||
|
@ -81,12 +81,16 @@ export const getRectangleCallExpressions = (
|
|||||||
createLabeledArg(
|
createLabeledArg(
|
||||||
ARG_END_ABSOLUTE,
|
ARG_END_ABSOLUTE,
|
||||||
createArrayExpression([
|
createArrayExpression([
|
||||||
createCallExpressionStdLib('profileStartX', [
|
createCallExpressionStdLibKw(
|
||||||
|
'profileStartX',
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
]),
|
[]
|
||||||
createCallExpressionStdLib('profileStartY', [
|
),
|
||||||
|
createCallExpressionStdLibKw(
|
||||||
|
'profileStartY',
|
||||||
createPipeSubstitution(),
|
createPipeSubstitution(),
|
||||||
]),
|
[]
|
||||||
|
),
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
]), // close the rectangle
|
]), // close the rectangle
|
||||||
|
@ -76,6 +76,11 @@ const SignIn = () => {
|
|||||||
authActor.send({ type: 'Log in', token })
|
authActor.send({ type: 'Log in', token })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cancelSignIn = async () => {
|
||||||
|
authActor.send({ type: 'Log out' })
|
||||||
|
setUserCode('')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main
|
<main
|
||||||
className="bg-primary h-screen grid place-items-stretch m-0 p-2"
|
className="bg-primary h-screen grid place-items-stretch m-0 p-2"
|
||||||
@ -128,7 +133,10 @@ const SignIn = () => {
|
|||||||
<p className="text-xs">
|
<p className="text-xs">
|
||||||
You should see the following code in your browser
|
You should see the following code in your browser
|
||||||
</p>
|
</p>
|
||||||
<p className="text-lg font-bold inline-flex gap-1">
|
<p
|
||||||
|
className="text-lg font-bold inline-flex gap-1"
|
||||||
|
data-testid="sign-in-user-code"
|
||||||
|
>
|
||||||
{userCode.split('').map((char, i) => (
|
{userCode.split('').map((char, i) => (
|
||||||
<span
|
<span
|
||||||
key={i}
|
key={i}
|
||||||
@ -141,6 +149,17 @@ const SignIn = () => {
|
|||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</p>
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={toSync(cancelSignIn, reportRejection)}
|
||||||
|
className={
|
||||||
|
'm-0 mt-8 w-fit flex gap-4 items-center px-3 py-1 ' +
|
||||||
|
'!border-transparent !text-lg !text-chalkboard-10 !bg-primary hover:hue-rotate-15'
|
||||||
|
}
|
||||||
|
data-testid="cancel-sign-in-button"
|
||||||
|
>
|
||||||
|
<CustomIcon name="arrowLeft" className="w-6 h-6" />
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -187,7 +206,7 @@ const SignIn = () => {
|
|||||||
'm-0 mt-8 flex gap-4 items-center px-3 py-1 ' +
|
'm-0 mt-8 flex gap-4 items-center px-3 py-1 ' +
|
||||||
'!border-transparent !text-lg !text-chalkboard-10 !bg-primary hover:hue-rotate-15'
|
'!border-transparent !text-lg !text-chalkboard-10 !bg-primary hover:hue-rotate-15'
|
||||||
}
|
}
|
||||||
data-testid="sign-in-button"
|
data-testid="view-sample-button"
|
||||||
>
|
>
|
||||||
View this sample
|
View this sample
|
||||||
<CustomIcon name="arrowRight" className="w-6 h-6" />
|
<CustomIcon name="arrowRight" className="w-6 h-6" />
|
||||||
|
Reference in New Issue
Block a user