Skip to content

Commit 0b4ee2d

Browse files
authored
Merge pull request #10297 from gitbutlerapp/fix-delete-project
FIx: Delete project & e2e
2 parents 8d685e9 + c6cd4ef commit 0b4ee2d

File tree

8 files changed

+87
-15
lines changed

8 files changed

+87
-15
lines changed

apps/desktop/src/components/ChromeSidebar.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
<div class="bottom__primary-actions">
276276
<div>
277277
<Button
278+
testId={TestId.ChromeSideBarProjectSettingsButton}
278279
kind="outline"
279280
onclick={() => {
280281
openProjectSettings(projectId);

apps/desktop/src/components/GlobalModal.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
return {
4646
state: modalState,
4747
props: {
48-
testId: 'general-settings-modal',
48+
testId: TestId.GeneralSettingsModal,
4949
closeButton: true,
5050
width: 820,
5151
noPadding: true
@@ -56,7 +56,7 @@
5656
return {
5757
state: modalState,
5858
props: {
59-
testId: 'project-settings-modal',
59+
testId: TestId.ProjectSettingsModal,
6060
closeButton: true,
6161
width: 820,
6262
noPadding: true

apps/desktop/src/components/RemoveProjectButton.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { Button, Modal } from '@gitbutler/ui';
2+
import { Button, Modal, TestId } from '@gitbutler/ui';
33
44
interface Props {
55
projectTitle?: string;
@@ -36,6 +36,7 @@
3636
</script>
3737

3838
<Button
39+
testId={TestId.ProjectDeleteButton}
3940
style="error"
4041
kind={outlineStyle ? 'outline' : 'solid'}
4142
icon="bin-small"
@@ -66,6 +67,7 @@
6667

6768
{#snippet controls()}
6869
<Button
70+
testId={TestId.ProjectDeleteModalConfirm}
6971
style="error"
7072
kind="outline"
7173
reversedDirection

apps/desktop/src/components/RemoveProjectForm.svelte

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import RemoveProjectButton from '$components/RemoveProjectButton.svelte';
55
import { showError } from '$lib/notifications/toasts';
66
import { PROJECTS_SERVICE } from '$lib/project/projectsService';
7+
import { useSettingsModal } from '$lib/settings/settingsModal.svelte';
78
import { inject } from '@gitbutler/core/context';
89
910
import { SectionCard, chipToasts } from '@gitbutler/ui';
@@ -12,13 +13,15 @@
1213
1314
const projectsService = inject(PROJECTS_SERVICE);
1415
const projectResult = $derived(projectsService.getProject(projectId));
16+
const { closeSettings } = useSettingsModal();
1517
1618
let isDeleting = $state(false);
1719
1820
async function onDeleteClicked() {
1921
isDeleting = true;
2022
try {
2123
await projectsService.deleteProject(projectId);
24+
closeSettings();
2225
goto('/');
2326
chipToasts.success('Project deleted');
2427
} catch (err: any) {

apps/desktop/src/lib/backend/web.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,17 @@ class WebDiskStore implements DiskStore {
4444

4545
async get<T>(key: string, defaultValue: undefined): Promise<T | undefined>;
4646
async get<T>(key: string, defaultValue: T): Promise<T>;
47-
async get<T>(_: string, defaultValue?: T): Promise<T | undefined> {
47+
async get<T>(key: string, defaultValue?: T): Promise<T | undefined> {
4848
// TODO: Implement this for the web version
4949
// This is a no-op for the web version
50-
return defaultValue;
50+
const fromCookie = getCookie(`disk-store-override:${key}`);
51+
try {
52+
const parsed = fromCookie ? (JSON.parse(fromCookie) as T) : undefined;
53+
return parsed ?? defaultValue;
54+
} catch (error) {
55+
console.error('Error parsing disk store value from cookie', error);
56+
return defaultValue;
57+
}
5158
}
5259
}
5360

e2e/playwright/src/setup.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,15 @@ function spawnProcess(
197197
return child;
198198
}
199199

200-
/**
201-
* Set the project path cookie in the browser context.
202-
*
203-
* This is needed in order for the Frontend to be able to know the absolute paths of the
204-
* project files. The web file picker is not able to get absolute paths for security reasons.
205-
*/
206-
async function setProjectPathCookie(context: BrowserContext, workdir: string): Promise<void> {
207-
// Set the information about the workdir
200+
export async function setCookie(
201+
name: string,
202+
value: string,
203+
context: BrowserContext
204+
): Promise<void> {
208205
await context.addCookies([
209206
{
210-
name: 'PROJECT_PATH',
211-
value: workdir,
207+
name,
208+
value,
212209
domain: 'localhost',
213210
path: '/',
214211
httpOnly: false,
@@ -218,6 +215,17 @@ async function setProjectPathCookie(context: BrowserContext, workdir: string): P
218215
]);
219216
}
220217

218+
/**
219+
* Set the project path cookie in the browser context.
220+
*
221+
* This is needed in order for the Frontend to be able to know the absolute paths of the
222+
* project files. The web file picker is not able to get absolute paths for security reasons.
223+
*/
224+
async function setProjectPathCookie(context: BrowserContext, workdir: string): Promise<void> {
225+
// Set the information about the workdir
226+
await setCookie('PROJECT_PATH', workdir, context);
227+
}
228+
221229
async function runCommand(
222230
command: string,
223231
args: string[],
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { getBaseURL, type GitButler, setCookie, startGitButler } from '../src/setup.ts';
2+
import { clickByTestId, waitForTestId, waitForTestIdToNotExist } from '../src/util.ts';
3+
import { test } from '@playwright/test';
4+
5+
let gitbutler: GitButler;
6+
7+
test.use({
8+
baseURL: getBaseURL()
9+
});
10+
11+
test.afterEach(async () => {
12+
gitbutler?.destroy();
13+
});
14+
15+
test('should be able to delete the last project gracefuly', async ({ page, context }, testInfo) => {
16+
const workdir = testInfo.outputPath('workdir');
17+
const configdir = testInfo.outputPath('config');
18+
gitbutler = await startGitButler(workdir, configdir, context);
19+
20+
// Override the analytics confirmation so we don't see the page later
21+
await setCookie('disk-store-override:appAnalyticsConfirmed', 'true', context);
22+
23+
await gitbutler.runScript('project-with-remote-branches.sh');
24+
25+
await page.goto('/');
26+
27+
// Should load the workspace
28+
await waitForTestId(page, 'workspace-view');
29+
30+
// Open project settings
31+
await clickByTestId(page, 'chrome-sidebar-project-settings-button');
32+
33+
await waitForTestId(page, 'project-settings-modal');
34+
35+
const deleteProjectButton = await waitForTestId(page, 'project-delete-button');
36+
await deleteProjectButton.scrollIntoViewIfNeeded();
37+
await deleteProjectButton.click();
38+
39+
await clickByTestId(page, 'project-delete-modal-confirm');
40+
41+
await waitForTestIdToNotExist(page, 'project-delete-modal-confirm');
42+
await waitForTestIdToNotExist(page, 'project-delete-button');
43+
await waitForTestIdToNotExist(page, 'project-settings-modal');
44+
45+
await waitForTestId(page, 'welcome-page');
46+
});

packages/ui/src/lib/utils/testIds.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,18 @@ export enum TestId {
130130
ProjectSetupPageTargetContinueButton = 'set-base-branch',
131131
ProjectSetupGitAuthPage = 'project-setup-git-auth-page',
132132
ProjectSetupGitAuthPageButton = 'accept-git-auth',
133+
ProjectDeleteButton = 'project-delete-button',
134+
ProjectDeleteModalConfirm = 'project-delete-modal-confirm',
133135
AddProjectAlreadyExistsModal = 'add-project-already-exists-modal',
134136
AddProjectAlreadyExistsModalOpenProjectButton = 'add-project-already-exists-modal-open-project-button',
135137
AddProjectBareRepoModal = 'add-project-bare-repo-modal',
136138
AddProjectNoDotGitDirectoryModal = 'add-project-no-dot-git-directory-modal',
137139
AddProjectNotAGitRepoModal = 'add-project-not-a-git-repo-modal',
138140
ChromeHeaderProjectSelector = 'chrome-header-project-selector',
139141
ChromeHeaderProjectSelectorAddLocalProject = 'chrome-header-project-selector-add-local-project',
142+
ChromeSideBarProjectSettingsButton = 'chrome-sidebar-project-settings-button',
143+
ProjectSettingsModal = 'project-settings-modal',
144+
GeneralSettingsModal = 'general-settings-modal',
140145
SyncButton = 'sync-button',
141146
EditMode = 'edit-mode',
142147
EditModeSaveAndExitButton = 'edit-mode-save-and-exit-button',

0 commit comments

Comments
 (0)