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('');