Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Playwright Tests

on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]

jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./client
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: client/playwright-report/
retention-days: 30
4 changes: 4 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ Full ecosystem spec: [../docs/ARCHITECTURE.md](../docs/ARCHITECTURE.md) (section
- `SUPABASE_URL`
- `SUPABASE_SERVICE_ROLE_KEY`

## Resource Guidelines
- **CPU**: 100m requests, 500m limits
- **Memory**: 256Mi requests, 512Mi limits
These resources are managed by HPA targeting 70% CPU usage.
---

## Database Backups & Restore
Expand Down
14 changes: 14 additions & 0 deletions backend/k8s/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: tikka-backend
labels:
app: tikka-backend
spec:
replicas: 2
namespace: default
labels:
app: tikka-backend
Expand All @@ -17,6 +21,16 @@ spec:
spec:
containers:
- name: tikka-backend
image: tikka-backend:latest
ports:
- containerPort: 3000
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
image: crackedstudio/tikka-backend:latest
ports:
- containerPort: 3001
Expand Down
18 changes: 18 additions & 0 deletions backend/k8s/hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: tikka-backend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: tikka-backend
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
9 changes: 9 additions & 0 deletions backend/k8s/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: tikka-backend-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: tikka-backend
19 changes: 19 additions & 0 deletions client/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
import { defineConfig } from '@playwright/test';

export default defineConfig({
Expand Down
69 changes: 69 additions & 0 deletions client/src/components/cards/FeaturedRaffleCardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";
import Line from "../../assets/svg/Line";

const FeaturedRaffleCardSkeleton: React.FC = () => {
return (
<div
className="w-full bg-[#11172E] p-4 md:p-6 lg:p-8 rounded-3xl border border-[#1F263F] my-5 animate-pulse"
aria-busy="true"
aria-label="Loading featured raffle"
>
<div className="flex flex-col gap-6 md:flex-row md:gap-8 items-stretch">
{/* Image Placeholder */}
<div className="w-full md:w-1/2 h-64 md:h-auto bg-[#242B46] rounded-2xl" />

{/* Content */}
<div className="w-full md:w-1/2 flex flex-col space-y-6">
{/* Title & Body Placeholder */}
<div className="space-y-3">
<div className="h-8 bg-[#242B46] rounded w-3/4" />
<div className="h-4 bg-[#242B46] rounded w-full" />
<div className="h-4 bg-[#242B46] rounded w-5/6" />
</div>

<Line />

{/* Prize + Countdown Placeholder */}
<div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
<div className="space-y-2">
<div className="h-4 bg-[#242B46] rounded w-20" />
<div className="h-6 bg-[#242B46] rounded w-32" />
</div>

<div className="sm:text-right space-y-2">
<div className="h-4 bg-[#242B46] rounded w-16 ml-auto" />
<div className="flex justify-start sm:justify-end gap-1">
<div className="h-6 w-8 bg-[#242B46] rounded" />
<div className="h-6 w-8 bg-[#242B46] rounded" />
<div className="h-6 w-8 bg-[#242B46] rounded" />
<div className="h-6 w-8 bg-[#242B46] rounded" />
</div>
</div>
</div>

<Line />

{/* Ticket & Entries Placeholder */}
<div className="flex flex-wrap items-center justify-between gap-4">
<div className="space-y-2">
<div className="h-3 bg-[#242B46] rounded w-16" />
<div className="h-4 bg-[#242B46] rounded w-12" />
</div>
<div className="space-y-2">
<div className="h-3 bg-[#242B46] rounded w-12" />
<div className="h-4 bg-[#242B46] rounded w-8" />
</div>
</div>

{/* Progress Placeholder */}
<div className="w-full h-2 bg-[#242B46] rounded-full" />

{/* CTA Placeholder */}
<div className="w-full h-14 bg-[#242B46] rounded-xl self-stretch md:self-start md:w-3/4 lg:w-1/2" />
</div>
</div>
</div>
);
};

export default FeaturedRaffleCardSkeleton;
53 changes: 53 additions & 0 deletions client/src/components/cards/RaffleCardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from "react";
import Line from "../../assets/svg/Line";

const RaffleCardSkeleton: React.FC = () => {
return (
<div
className="w-full bg-[#11172E] p-4 rounded-3xl flex flex-col space-y-4 animate-pulse"
aria-busy="true"
aria-label="Loading raffle"
>
{/* Image Placeholder */}
<div className="w-full h-48 bg-[#242B46] rounded-3xl" />

{/* Title & Prize Placeholder */}
<div className="space-y-2">
<div className="h-6 bg-[#242B46] rounded w-3/4" />
<div className="h-4 bg-[#242B46] rounded w-1/2" />
</div>

{/* Countdown Placeholder */}
<div>
<Line />
<div className="flex justify-center space-x-1 my-2">
<div className="h-6 w-8 bg-[#242B46] rounded" />
<div className="h-6 w-8 bg-[#242B46] rounded" />
<div className="h-6 w-8 bg-[#242B46] rounded" />
<div className="h-6 w-8 bg-[#242B46] rounded" />
</div>
<Line />
</div>

{/* Ticket & Entries Placeholder */}
<div className="flex justify-between">
<div className="space-y-1">
<div className="h-3 bg-[#242B46] rounded w-16" />
<div className="h-4 bg-[#242B46] rounded w-12" />
</div>
<div className="space-y-1">
<div className="h-3 bg-[#242B46] rounded w-12" />
<div className="h-4 bg-[#242B46] rounded w-8" />
</div>
</div>

{/* Progress Placeholder */}
<div className="w-full h-2 bg-[#242B46] rounded-full mt-2" />

{/* Button Placeholder */}
<div className="w-full h-14 bg-[#242B46] rounded-xl mt-4" />
</div>
);
};

export default RaffleCardSkeleton;
1 change: 1 addition & 0 deletions client/src/components/landing/TrendingRaffles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import RaffleCard from "../cards/RaffleCard";
import RaffleCardSkeleton from "../cards/RaffleCardSkeleton";
import TrendingTab from "./TrendingTab";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
Expand Down
2 changes: 2 additions & 0 deletions client/src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import BrowseRaffles from "../components/home/BrowseRaffles";
import RaffleCardSkeleton from "../components/cards/RaffleCardSkeleton";
import FeaturedRaffleCardSkeleton from "../components/cards/FeaturedRaffleCardSkeleton";
import FeaturedRaffle from "../components/landing/FeaturedRaffle";
import TrendingRaffles from "../components/landing/TrendingRaffles";
import VerifiedBadge from "../components/VerifiedBadge";
Expand Down
62 changes: 62 additions & 0 deletions client/tests/raffle.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { test, expect } from '@playwright/test';

test.describe('Raffle Flows', () => {
test.beforeEach(async ({ page }) => {
// Mock the raffles API so the home page can load
await page.route('**/api/raffles*', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
data: [],
total: 0,
}),
});
});
});

test('Creating a raffle shows a success message', async ({ page }) => {
// Navigate to the create raffle page
await page.goto('/create-raffle');

// Fill in raffle creation form (assumed fields based on standard implementations)
await page.fill('input[name="title"]', 'Test Raffle');
await page.fill('textarea[name="description"]', 'Win this amazing test item!');
await page.fill('input[name="ticketPrice"]', '5');

// Mock the submission endpoint to simulate success
await page.route('**/api/raffles/create', async (route) => {
await route.fulfill({
status: 201,
contentType: 'application/json',
body: JSON.stringify({ id: 99, success: true }),
});
});

// Click submit and wait for success state
await page.click('button[type="submit"]');

// Asser expected behavior
await expect(page.locator('text=Raffle Created')).toBeVisible();
});

test('Buying a ticket executes successfully', async ({ page }) => {
// Navigate to a details page
await page.goto('/details?raffle=99');

// Mock contract network call for ticket purchase
await page.route('**/api/contract/buy', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ success: true, txHash: '0x123abc' }),
});
});

// Click buy button
await page.click('button:has-text("Buy Ticket")');

// Wait for the success indication
await expect(page.locator('text=Purchase Successful')).toBeVisible();
});
});
5 changes: 5 additions & 0 deletions indexer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,8 @@ src/
├── 1700000000004-CreatePlatformStats.ts
└── 1700000000005-CreateIndexerCursor.ts
```

## Resource Guidelines
- **CPU**: 200m requests, 1000m limits
- **Memory**: 512Mi requests, 1Gi limits
Indexer is optimized for single-replica execution.
18 changes: 18 additions & 0 deletions oracle/k8s/hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: tikka-oracle-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: tikka-oracle
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Loading
Loading