diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..6d929769 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,90 @@ +name: Bug Report +description: Report a bug to help us improve +title: "[Bug]: " +labels: [bug] +assignees: [] + +body: + - type: dropdown + id: environment + attributes: + label: Where are you using the app? + options: + - Cloud (Hosted by Us) + - Self-Hosted (OSS) with Docker + - Self-Hosted (OSS) without Docker + validations: + required: true + + - type: input + id: app_version + attributes: + label: App Version + description: Enter the version number you are using (if known). + placeholder: "e.g., v1.2.3" + validations: + required: false + + - type: input + id: browser + attributes: + label: Browser + description: Which browser are you using? + placeholder: "e.g., Chrome 124, Firefox 115, Safari 17" + validations: + required: true + + - type: input + id: operating_system + attributes: + label: Operating System + description: Your operating system and version. + placeholder: "e.g., Windows 11, macOS Sonoma, Ubuntu 22.04" + validations: + required: true + + - type: textarea + id: steps_to_reproduce + attributes: + label: Steps to Reproduce + description: How can we reproduce the problem? + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. Scroll down to '...' + 4. See error + validations: + required: true + + - type: textarea + id: expected_behavior + attributes: + label: Expected Behavior + description: What did you expect to happen instead? + validations: + required: true + + - type: textarea + id: actual_behavior + attributes: + label: Actual Behavior + description: What actually happened? + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Relevant Logs or Screenshots + description: Please paste any logs, screenshots, or console errors if available. + placeholder: "Paste logs or upload screenshots." + validations: + required: false + + - type: textarea + id: additional_context + attributes: + label: Additional Context + description: Anything else we should know? + validations: + required: false diff --git a/index.html b/index.html index c1ebd718..d6a1a5f8 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ Maxun | Open Source No Code Web Data Extraction Platform diff --git a/nginx.conf b/nginx.conf index 1ea52146..c3651437 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,45 +1,24 @@ server { listen 80; + server_name _; + root /var/www/maxun; + index index.html; + + # Serve the frontend location / { - root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } - - location /api { - proxy_pass http://localhost:8080; + + # Proxy for backend + location ^/(auth|storage|record|workflow|robot|proxy|api-docs|api)(/|$) { + proxy_pass http://localhost:8080; # change as per your setup proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - - # Add timeout configurations - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - - # Add error handling - proxy_intercept_errors on; - error_page 502 503 504 /50x.html; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; } - - location ~ ^/(record|workflow|storage|auth|integration|proxy|api-docs) { - proxy_pass http://localhost:8080; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'keep-alive'; # Ensure connections remain open - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - - # Timeout configurations - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - - # Error handling for these routes - proxy_intercept_errors on; - error_page 502 503 504 /50x.html; - } -} \ No newline at end of file +} diff --git a/server/src/browser-management/inputHandlers.ts b/server/src/browser-management/inputHandlers.ts index 598c528e..4e6d5d19 100644 --- a/server/src/browser-management/inputHandlers.ts +++ b/server/src/browser-management/inputHandlers.ts @@ -224,9 +224,15 @@ const onMousemove = async (socket: AuthenticatedSocket, coordinates: Coordinates */ const handleMousemove = async (generator: WorkflowGenerator, page: Page, { x, y }: Coordinates) => { try { + if (page.isClosed()) { + logger.log('debug', `Ignoring mousemove event: page is closed`); + return; + } await page.mouse.move(x, y); throttle(async () => { - await generator.generateDataForHighlighter(page, { x, y }); + if (!page.isClosed()) { + await generator.generateDataForHighlighter(page, { x, y }); + } }, 100)(); logger.log('debug', `Moved over position x:${x}, y:${y}`); } catch (e) { @@ -402,7 +408,7 @@ const handleChangeUrl = async (generator: WorkflowGenerator, page: Page, url: st if (url) { await generator.onChangeUrl(url, page); try { - await page.goto(url); + await page.goto(url, { waitUntil: 'networkidle', timeout: 10000 }); logger.log('debug', `Went to ${url}`); } catch (e) { const { message } = e as Error; @@ -514,4 +520,4 @@ const registerInputHandlers = (socket: Socket) => { socket.on("action", (data) => onGenerateAction(authSocket, data)); }; -export default registerInputHandlers; \ No newline at end of file +export default registerInputHandlers; diff --git a/server/src/pgboss-worker.ts b/server/src/pgboss-worker.ts index d6960a05..54a70697 100644 --- a/server/src/pgboss-worker.ts +++ b/server/src/pgboss-worker.ts @@ -93,7 +93,7 @@ async function resetBrowserState(browser: RemoteBrowser): Promise { } // Navigate to blank page to reset state - await currentPage.goto('about:blank'); + await currentPage.goto('about:blank', { waitUntil: 'networkidle', timeout: 10000 }); // Clear browser storage await currentPage.evaluate(() => { diff --git a/server/src/routes/record.ts b/server/src/routes/record.ts index 411767c2..374f837a 100644 --- a/server/src/routes/record.ts +++ b/server/src/routes/record.ts @@ -10,6 +10,7 @@ import { getRemoteBrowserCurrentUrl, getRemoteBrowserCurrentTabs, getActiveBrowserIdByState, + destroyRemoteBrowser, } from '../browser-management/controller'; import { chromium } from 'playwright-extra'; import stealthPlugin from 'puppeteer-extra-plugin-stealth'; @@ -146,8 +147,8 @@ router.get('/stop/:browserId', requireSignIn, async (req: AuthenticatedRequest, }); if (!jobId) { - const browserId = initializeRemoteBrowserForRecording(req.user.id); - return res.send( browserId ); + await destroyRemoteBrowser(req.params.browserId, req.user.id); + return res.send(false); } logger.log('info', `Queued browser destruction job: ${jobId}, waiting for completion...`); diff --git a/src/components/recorder/RightSidePanel.tsx b/src/components/recorder/RightSidePanel.tsx index 80180823..89a2c486 100644 --- a/src/components/recorder/RightSidePanel.tsx +++ b/src/components/recorder/RightSidePanel.tsx @@ -441,6 +441,8 @@ export const RightSidePanel: React.FC = ({ onFinishCapture } }); resetListState(); + stopPaginationMode(); + stopLimitMode(); setShowPaginationOptions(false); setShowLimitOptions(false); setCaptureStage('initial'); diff --git a/src/context/browserActions.tsx b/src/context/browserActions.tsx index c993dbce..2c93df8b 100644 --- a/src/context/browserActions.tsx +++ b/src/context/browserActions.tsx @@ -147,6 +147,7 @@ export const ActionProvider = ({ children }: { children: ReactNode }) => { const stopGetList = () => { setGetList(false); + socket?.emit('setGetList', { getList: false }); setPaginationType(''); setLimitType(''); setCustomLimit('');