security: remove credential automation from releases
This commit is contained in:
parent
f342ea8640
commit
547d4ad97a
9 changed files with 11 additions and 647 deletions
|
|
@ -53,6 +53,7 @@ jobs:
|
||||||
https://d3ro.chanpaca.net/release-identity.json \
|
https://d3ro.chanpaca.net/release-identity.json \
|
||||||
--output release-identity.live.json
|
--output release-identity.live.json
|
||||||
node -e "const fs=require('node:fs'); const live=JSON.parse(fs.readFileSync('release-identity.live.json','utf8')); if(live.commit!==process.env.GITHUB_SHA) throw new Error('public commit mismatch'); const expected=require('./release/product-version.json').version; if(live.version!==expected) throw new Error('public version mismatch')"
|
node -e "const fs=require('node:fs'); const live=JSON.parse(fs.readFileSync('release-identity.live.json','utf8')); if(live.commit!==process.env.GITHUB_SHA) throw new Error('public commit mismatch'); const expected=require('./release/product-version.json').version; if(live.version!==expected) throw new Error('public version mismatch')"
|
||||||
|
node scripts/ci/verify-android-app-links.mjs
|
||||||
curl --fail --silent --show-error https://d3ro.chanpaca.net/ --output /dev/null
|
curl --fail --silent --show-error https://d3ro.chanpaca.net/ --output /dev/null
|
||||||
curl --fail --silent --show-error https://d3ro.chanpaca.net/privacy/ --output /dev/null
|
curl --fail --silent --show-error https://d3ro.chanpaca.net/privacy/ --output /dev/null
|
||||||
curl --fail --silent --show-error https://d3ro.chanpaca.net/terms/ --output /dev/null
|
curl --fail --silent --show-error https://d3ro.chanpaca.net/terms/ --output /dev/null
|
||||||
|
|
|
||||||
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -70,3 +70,13 @@ apps/mobile-rn/.maestro/*.junit.xml
|
||||||
.chrome-interactive-profile/
|
.chrome-interactive-profile/
|
||||||
.chrome-playwright-profile/
|
.chrome-playwright-profile/
|
||||||
.playwright-oauth-profile/
|
.playwright-oauth-profile/
|
||||||
|
|
||||||
|
# Local browser/account automation. These scripts may reference developer-only
|
||||||
|
# credential sources and must never be part of a release checkout.
|
||||||
|
/scripts/capture-forgejo-release-live.js
|
||||||
|
/scripts/capture-forgejo-repo.js
|
||||||
|
/scripts/inspect-forgejo-runners.js
|
||||||
|
/scripts/playwright-fill-all-live-ad-portals.js
|
||||||
|
/scripts/playwright-live-ad-portals-signup.js
|
||||||
|
/scripts/playwright-submit-applovin.js
|
||||||
|
/scripts/register-and-inspect-ad-portals.js
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
// scripts/capture-forgejo-release-live.js
|
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
async function capture() {
|
|
||||||
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
||||||
const context = await browser.newContext({ viewport: { width: 1440, height: 960 }, deviceScaleFactor: 2 });
|
|
||||||
const page = await context.newPage();
|
|
||||||
|
|
||||||
console.log('Logging in to Forgejo...');
|
|
||||||
await page.goto('https://git.chanpaca.net/user/login', { waitUntil: 'networkidle' });
|
|
||||||
await page.fill('input[name="user_name"]', 'yunchan');
|
|
||||||
await page.fill('input[name="password"]', 'ONVI2v4J#y');
|
|
||||||
await page.click('button[type="submit"]');
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
console.log('Navigating to releases...');
|
|
||||||
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice/releases', { waitUntil: 'networkidle' });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
const shotPath = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/git_server/05_forgejo_v1_0_0_official_release_with_binary.png';
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: true });
|
|
||||||
console.log('Saved:', shotPath);
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
capture().catch(console.error);
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
// scripts/capture-forgejo-repo.js
|
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/git_server';
|
|
||||||
|
|
||||||
async function captureRepo() {
|
|
||||||
if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
||||||
|
|
||||||
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
||||||
const context = await browser.newContext({
|
|
||||||
viewport: { width: 1440, height: 960 },
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await context.newPage();
|
|
||||||
|
|
||||||
// Login to Forgejo
|
|
||||||
console.log('Logging in to Forgejo git.chanpaca.net...');
|
|
||||||
await page.goto('https://git.chanpaca.net/user/login', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.fill('input[name="user_name"]', 'yunchan');
|
|
||||||
await page.fill('input[name="password"]', 'ONVI2v4J#y');
|
|
||||||
await page.click('button:has-text("Sign in"), button:has-text("로그인"), button[type="submit"]');
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
// Navigate to d3ro-voice repository
|
|
||||||
console.log('Navigating to https://git.chanpaca.net/yunchan/d3ro-voice...');
|
|
||||||
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '01_forgejo_d3ro_voice_repo_live.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: false });
|
|
||||||
console.log('Screenshot saved to:', shotPath);
|
|
||||||
|
|
||||||
// Navigate to releases / tags
|
|
||||||
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice/releases', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
const tagShotPath = path.join(OUTPUT_DIR, '02_forgejo_d3ro_voice_releases_tags.png');
|
|
||||||
await page.screenshot({ path: tagShotPath, fullPage: false });
|
|
||||||
console.log('Releases screenshot saved to:', tagShotPath);
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
captureRepo().catch(console.error);
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
// scripts/inspect-forgejo-runners.js
|
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/git_server';
|
|
||||||
|
|
||||||
async function inspectRunners() {
|
|
||||||
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
||||||
const context = await browser.newContext({ viewport: { width: 1440, height: 960 } });
|
|
||||||
const page = await context.newPage();
|
|
||||||
|
|
||||||
console.log('Logging in to Forgejo...');
|
|
||||||
await page.goto('https://git.chanpaca.net/user/login', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.fill('input[name="user_name"]', 'yunchan');
|
|
||||||
await page.fill('input[name="password"]', 'ONVI2v4J#y');
|
|
||||||
await page.click('button:has-text("Sign in"), button:has-text("로그인"), button[type="submit"]');
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
// Check Admin Actions Runners
|
|
||||||
console.log('Navigating to Admin Actions Runners...');
|
|
||||||
await page.goto('https://git.chanpaca.net/admin/actions/runners', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
const shot1 = path.join(OUTPUT_DIR, '03_forgejo_admin_runners.png');
|
|
||||||
await page.screenshot({ path: shot1, fullPage: false });
|
|
||||||
console.log('Admin Runners screenshot saved:', shot1);
|
|
||||||
|
|
||||||
// Check Repo Actions tab
|
|
||||||
console.log('Navigating to Repo Actions...');
|
|
||||||
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice/actions', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
const shot2 = path.join(OUTPUT_DIR, '04_forgejo_repo_actions.png');
|
|
||||||
await page.screenshot({ path: shot2, fullPage: false });
|
|
||||||
console.log('Repo Actions screenshot saved:', shot2);
|
|
||||||
|
|
||||||
// Extract runner details from page
|
|
||||||
await page.goto('https://git.chanpaca.net/admin/actions/runners');
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const runnerRows = await page.locator('table tr, .runner-item, .flex-list-item').allInnerTexts();
|
|
||||||
console.log('RUNNER ROWS FOUND:', JSON.stringify(runnerRows, null, 2));
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
inspectRunners().catch(console.error);
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
// scripts/playwright-fill-all-live-ad-portals.js
|
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/live_portal_signups';
|
|
||||||
|
|
||||||
const CREDS = {
|
|
||||||
email: 'yunchanpaca@gmail.com',
|
|
||||||
password: 'ONVI2v4J#y',
|
|
||||||
firstName: 'Yunchan',
|
|
||||||
lastName: 'Park',
|
|
||||||
fullName: 'Yunchan Park',
|
|
||||||
company: 'D3RO Voice AI',
|
|
||||||
url: 'https://d3ro.app',
|
|
||||||
};
|
|
||||||
|
|
||||||
async function fillAllLiveAdPortals() {
|
|
||||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
||||||
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const browser = await chromium.launch({
|
|
||||||
channel: 'msedge',
|
|
||||||
headless: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const context = await browser.newContext({
|
|
||||||
viewport: { width: 1440, height: 1080 },
|
|
||||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1. AppLovin MAX
|
|
||||||
try {
|
|
||||||
console.log('[1/3] Interacting with AppLovin MAX Signup...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://dash.applovin.com/signup', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
const nameInput = page.locator('input[placeholder*="name" i]').first();
|
|
||||||
const emailInput = page.locator('input[type="email"]').first();
|
|
||||||
const companyInput = page.locator('input[placeholder*="company" i]').first();
|
|
||||||
const websiteInput = page.locator('input[placeholder*="applovin.com" i], input[placeholder*="site" i]').first();
|
|
||||||
const storeUrlInput = page.locator('input[placeholder*="store" i]').first();
|
|
||||||
const passInputs = page.locator('input[type="password"]');
|
|
||||||
|
|
||||||
if (await nameInput.isVisible()) await nameInput.fill(CREDS.fullName);
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
|
|
||||||
if (await companyInput.isVisible()) await companyInput.fill(CREDS.company);
|
|
||||||
if (await websiteInput.isVisible()) await websiteInput.fill(CREDS.url);
|
|
||||||
if (await storeUrlInput.isVisible()) await storeUrlInput.fill('https://d3ro.app/download/desktop');
|
|
||||||
|
|
||||||
// Fill both password and confirm password
|
|
||||||
const count = await passInputs.count();
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
await passInputs.nth(i).fill(CREDS.password);
|
|
||||||
}
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '02_applovin_max_form_filled_complete.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: true });
|
|
||||||
console.log('AppLovin MAX complete screenshot saved:', shotPath);
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('AppLovin error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Mintegral Developer Signup
|
|
||||||
try {
|
|
||||||
console.log('[2/3] Interacting with Mintegral Signup...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://www.mintegral.com/en/signup', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
const emailInput = page.locator('input[type="email"], input[placeholder*="email" i]').first();
|
|
||||||
const passInputs = page.locator('input[type="password"]');
|
|
||||||
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
|
|
||||||
const count = await passInputs.count();
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
await passInputs.nth(i).fill(CREDS.password);
|
|
||||||
}
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '03_mintegral_signup_filled_complete.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: false });
|
|
||||||
console.log('Mintegral complete screenshot saved:', shotPath);
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Mintegral error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Unity ID Registration
|
|
||||||
try {
|
|
||||||
console.log('[3/3] Interacting with Unity ID Registration...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://id.unity.com/en/conversations/new', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
const emailInput = page.locator('input[type="email"]').first();
|
|
||||||
const passInput = page.locator('input[type="password"]').first();
|
|
||||||
const usernameInput = page.locator('input[name*="username" i]').first();
|
|
||||||
const fullnameInput = page.locator('input[name*="name" i]').first();
|
|
||||||
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
|
|
||||||
if (await passInput.isVisible()) await passInput.fill(CREDS.password);
|
|
||||||
if (await usernameInput.isVisible()) await usernameInput.fill('yunchanpaca');
|
|
||||||
if (await fullnameInput.isVisible()) await fullnameInput.fill(CREDS.fullName);
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '06_unity_cloud_signup_filled_complete.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: false });
|
|
||||||
console.log('Unity ID complete screenshot saved:', shotPath);
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Unity error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
console.log('--- All Direct Browser Actions Completed! ---');
|
|
||||||
}
|
|
||||||
|
|
||||||
fillAllLiveAdPortals().catch(console.error);
|
|
||||||
|
|
@ -1,214 +0,0 @@
|
||||||
// scripts/playwright-live-ad-portals-signup.js
|
|
||||||
// Playwright Automation: Navigates to live ad portals, fills publisher registration forms with user credentials, and captures progress.
|
|
||||||
|
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/live_portal_signups';
|
|
||||||
|
|
||||||
const USER_CREDENTIALS = {
|
|
||||||
email: 'yunchanpaca@gmail.com',
|
|
||||||
password: 'ONVI2v4J#y',
|
|
||||||
firstName: 'Yunchan',
|
|
||||||
lastName: 'Park',
|
|
||||||
fullName: 'Yunchan Park',
|
|
||||||
company: 'D3RO Voice AI',
|
|
||||||
appName: 'D3RO Voice AI (Desktop & Web AI Assistant)',
|
|
||||||
appUrl: 'https://d3ro.app',
|
|
||||||
monthlyImpressions: '100,000+',
|
|
||||||
country: 'South Korea',
|
|
||||||
};
|
|
||||||
|
|
||||||
async function runLiveAdPortalsSignup() {
|
|
||||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
||||||
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('--- Launching Playwright Browser Automation for Live Ad Portals Signup ---');
|
|
||||||
const browser = await chromium.launch({
|
|
||||||
channel: 'msedge',
|
|
||||||
headless: true, // headless mode for reliable capture in CLI environment
|
|
||||||
});
|
|
||||||
|
|
||||||
const context = await browser.newContext({
|
|
||||||
viewport: { width: 1440, height: 960 },
|
|
||||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0',
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = [];
|
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// 1. EthicalAds Publisher Application
|
|
||||||
// ==========================================
|
|
||||||
try {
|
|
||||||
console.log('[1/5] Navigating to EthicalAds Publisher Application...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://www.ethicalads.io/publishers/apply/', { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
// Fill form fields
|
|
||||||
const nameInput = page.locator('input[name="name"], input[id*="name"]').first();
|
|
||||||
const emailInput = page.locator('input[name="email"], input[type="email"], input[id*="email"]').first();
|
|
||||||
const siteInput = page.locator('input[name*="site"], input[name*="url"], input[id*="url"]').first();
|
|
||||||
const trafficInput = page.locator('input[name*="views"], input[name*="traffic"], select[name*="traffic"]').first();
|
|
||||||
|
|
||||||
if (await nameInput.isVisible()) await nameInput.fill(USER_CREDENTIALS.fullName);
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
|
|
||||||
if (await siteInput.isVisible()) await siteInput.fill(USER_CREDENTIALS.appUrl);
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '01_ethicalads_signup_filled.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: true });
|
|
||||||
results.push({ portal: 'EthicalAds', status: 'Form Filled & Captured', screenshot: shotPath });
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('EthicalAds signup error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// 2. AppLovin MAX Developer Signup
|
|
||||||
// ==========================================
|
|
||||||
try {
|
|
||||||
console.log('[2/5] Navigating to AppLovin MAX Developer Signup...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://dash.applovin.com/signup', { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
const emailInput = page.locator('input[name="email"], input[type="email"]').first();
|
|
||||||
const nameInput = page.locator('input[name="name"], input[name="fullName"]').first();
|
|
||||||
const companyInput = page.locator('input[name="company"], input[name="companyName"]').first();
|
|
||||||
const websiteInput = page.locator('input[name="website"], input[name="url"]').first();
|
|
||||||
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
|
|
||||||
if (await nameInput.isVisible()) await nameInput.fill(USER_CREDENTIALS.fullName);
|
|
||||||
if (await companyInput.isVisible()) await companyInput.fill(USER_CREDENTIALS.company);
|
|
||||||
if (await websiteInput.isVisible()) await websiteInput.fill(USER_CREDENTIALS.appUrl);
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '02_applovin_max_signup_filled.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: false });
|
|
||||||
results.push({ portal: 'AppLovin MAX', status: 'Form Filled & Captured', screenshot: shotPath });
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('AppLovin signup error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// 3. Mintegral Publisher / Developer Signup
|
|
||||||
// ==========================================
|
|
||||||
try {
|
|
||||||
console.log('[3/5] Navigating to Mintegral Publisher Signup...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://www.mintegral.com/en/signup', { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
const emailInput = page.locator('input[type="email"], input[placeholder*="email" i]').first();
|
|
||||||
const passwordInput = page.locator('input[type="password"]').first();
|
|
||||||
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
|
|
||||||
if (await passwordInput.isVisible()) await passwordInput.fill(USER_CREDENTIALS.password);
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '03_mintegral_signup_filled.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: false });
|
|
||||||
results.push({ portal: 'Mintegral', status: 'Form Filled & Captured', screenshot: shotPath });
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Mintegral signup error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// 4. Playwire Publisher Application Form
|
|
||||||
// ==========================================
|
|
||||||
try {
|
|
||||||
console.log('[4/5] Navigating to Playwire Publisher Application...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://www.playwire.com/contact-direct', { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
const firstNameInput = page.locator('input[name*="firstname" i]').first();
|
|
||||||
const lastNameInput = page.locator('input[name*="lastname" i]').first();
|
|
||||||
const emailInput = page.locator('input[name*="email" i], input[type="email"]').first();
|
|
||||||
const websiteInput = page.locator('input[name*="website" i], input[name*="url" i]').first();
|
|
||||||
|
|
||||||
if (await firstNameInput.isVisible()) await firstNameInput.fill(USER_CREDENTIALS.firstName);
|
|
||||||
if (await lastNameInput.isVisible()) await lastNameInput.fill(USER_CREDENTIALS.lastName);
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
|
|
||||||
if (await websiteInput.isVisible()) await websiteInput.fill(USER_CREDENTIALS.appUrl);
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '04_playwire_application_filled.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: true });
|
|
||||||
results.push({ portal: 'Playwire', status: 'Form Filled & Captured', screenshot: shotPath });
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Playwire signup error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// 5. BuySellAds (Carbon Ads) Publisher Portal
|
|
||||||
// ==========================================
|
|
||||||
try {
|
|
||||||
console.log('[5/5] Navigating to BuySellAds (Carbon) Publisher Portal...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://www.buysellads.com/publishers', { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
const applyButton = page.locator('a:has-text("Apply"), button:has-text("Apply"), a:has-text("Get Started")').first();
|
|
||||||
if (await applyButton.isVisible()) {
|
|
||||||
await applyButton.click();
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '05_buysellads_carbon_publisher_apply.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: true });
|
|
||||||
results.push({ portal: 'BuySellAds (Carbon)', status: 'Form Navigated & Captured', screenshot: shotPath });
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('BuySellAds signup error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================
|
|
||||||
// 6. Unity ID / Unity Gaming Services
|
|
||||||
// ==========================================
|
|
||||||
try {
|
|
||||||
console.log('[6/6] Navigating to Unity ID Registration...');
|
|
||||||
const page = await context.newPage();
|
|
||||||
await page.goto('https://id.unity.com/en/conversations/new', { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(3000);
|
|
||||||
|
|
||||||
const emailInput = page.locator('input[name="conversations_create_user_form[email]"], input[type="email"]').first();
|
|
||||||
const passwordInput = page.locator('input[name="conversations_create_user_form[password]"], input[type="password"]').first();
|
|
||||||
const usernameInput = page.locator('input[name="conversations_create_user_form[username]"], input[name*="username"]').first();
|
|
||||||
const fullnameInput = page.locator('input[name="conversations_create_user_form[full_name]"], input[name*="name"]').first();
|
|
||||||
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
|
|
||||||
if (await passwordInput.isVisible()) await passwordInput.fill(USER_CREDENTIALS.password);
|
|
||||||
if (await usernameInput.isVisible()) await usernameInput.fill('yunchanpaca');
|
|
||||||
if (await fullnameInput.isVisible()) await fullnameInput.fill(USER_CREDENTIALS.fullName);
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '06_unity_cloud_signup_filled.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: false });
|
|
||||||
results.push({ portal: 'Unity Ads (LevelPlay)', status: 'Form Filled & Captured', screenshot: shotPath });
|
|
||||||
await page.close();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Unity signup error:', err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(OUTPUT_DIR, 'signup_automation_summary.json'),
|
|
||||||
JSON.stringify(results, null, 2),
|
|
||||||
'utf8'
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('--- Playwright Live Ad Portals Signup Automation Finished Successfully! ---');
|
|
||||||
}
|
|
||||||
|
|
||||||
runLiveAdPortalsSignup().catch((err) => {
|
|
||||||
console.error('Live Ad Portals Signup Automation Error:', err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
// scripts/playwright-submit-applovin.js
|
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/live_portal_signups';
|
|
||||||
|
|
||||||
const CREDS = {
|
|
||||||
email: 'yunchanpaca@gmail.com',
|
|
||||||
password: 'ONVI2v4J#y',
|
|
||||||
fullName: 'Yunchan Park',
|
|
||||||
company: 'D3RO Voice AI',
|
|
||||||
url: 'https://d3ro.app',
|
|
||||||
};
|
|
||||||
|
|
||||||
async function submitAppLovin() {
|
|
||||||
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
||||||
const context = await browser.newContext({
|
|
||||||
viewport: { width: 1440, height: 1080 },
|
|
||||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await context.newPage();
|
|
||||||
console.log('Navigating to AppLovin MAX...');
|
|
||||||
await page.goto('https://dash.applovin.com/signup', { waitUntil: 'networkidle', timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
const nameInput = page.locator('input[placeholder*="name" i]').first();
|
|
||||||
const emailInput = page.locator('input[type="email"]').first();
|
|
||||||
const companyInput = page.locator('input[placeholder*="company" i]').first();
|
|
||||||
const websiteInput = page.locator('input[placeholder*="applovin.com" i], input[placeholder*="site" i]').first();
|
|
||||||
const storeUrlInput = page.locator('input[placeholder*="store" i]').first();
|
|
||||||
const passInputs = page.locator('input[type="password"]');
|
|
||||||
|
|
||||||
if (await nameInput.isVisible()) await nameInput.fill(CREDS.fullName);
|
|
||||||
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
|
|
||||||
if (await companyInput.isVisible()) await companyInput.fill(CREDS.company);
|
|
||||||
if (await websiteInput.isVisible()) await websiteInput.fill(CREDS.url);
|
|
||||||
if (await storeUrlInput.isVisible()) await storeUrlInput.fill('https://play.google.com/store/apps/details?id=ai.d3ro.voice');
|
|
||||||
|
|
||||||
const count = await passInputs.count();
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
await passInputs.nth(i).fill(CREDS.password);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scroll down
|
|
||||||
await page.evaluate(() => window.scrollBy(0, 400));
|
|
||||||
await page.waitForTimeout(1000);
|
|
||||||
|
|
||||||
// Check checkboxes
|
|
||||||
const checkboxes = page.locator('input[type="checkbox"]');
|
|
||||||
const cbCount = await checkboxes.count();
|
|
||||||
for (let i = 0; i < cbCount; i++) {
|
|
||||||
try {
|
|
||||||
await checkboxes.nth(i).check({ force: true });
|
|
||||||
} catch {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitBtn = page.locator('button:has-text("Sign up"), button:has-text("Create Account"), button[type="submit"]').first();
|
|
||||||
if (await submitBtn.isVisible()) {
|
|
||||||
console.log('Clicking Sign up button...');
|
|
||||||
await submitBtn.click();
|
|
||||||
await page.waitForTimeout(6000);
|
|
||||||
}
|
|
||||||
|
|
||||||
const shotPath = path.join(OUTPUT_DIR, '02_applovin_max_final_signup_state.png');
|
|
||||||
await page.screenshot({ path: shotPath, fullPage: true });
|
|
||||||
console.log('AppLovin MAX final response captured:', shotPath);
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
submitAppLovin().catch(console.error);
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
const { chromium } = require('@playwright/test');
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
const SCREENSHOT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/ad_portals';
|
|
||||||
const USER_EMAIL = 'yunchanpaca@gmail.com';
|
|
||||||
const APP_NAME = 'D3RO Voice';
|
|
||||||
const APP_URL = 'https://d3ro.voice.ai';
|
|
||||||
|
|
||||||
async function inspectAndRegisterPortals() {
|
|
||||||
if (!fs.existsSync(SCREENSHOT_DIR)) {
|
|
||||||
fs.mkdirSync(SCREENSHOT_DIR, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
||||||
const context = await browser.newContext({
|
|
||||||
viewport: { width: 1440, height: 900 },
|
|
||||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await context.newPage();
|
|
||||||
const results = [];
|
|
||||||
|
|
||||||
// 1. EthicalAds Publisher Portal
|
|
||||||
console.log('--- Inspecting Portal 1: EthicalAds ---');
|
|
||||||
try {
|
|
||||||
await page.goto('https://www.ethicalads.io/publishers/', { timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '01_ethicalads_publisher_landing.png') });
|
|
||||||
|
|
||||||
// Look for apply button or form
|
|
||||||
const applyLink = page.locator('a[href*="apply"], a[href*="contact"], a:has-text("Apply")').first();
|
|
||||||
if (await applyLink.isVisible()) {
|
|
||||||
await applyLink.click();
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '01b_ethicalads_apply_form.png') });
|
|
||||||
}
|
|
||||||
results.push({ name: 'EthicalAds', status: 'Inspected & Form Captured', type: 'Privacy-First Dev Ads', api: 'REST Decision API (/api/v1/decision/)' });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('EthicalAds inspection error:', err.message);
|
|
||||||
results.push({ name: 'EthicalAds', status: 'Inspected (Fallback)', type: 'Privacy-First Dev Ads', api: 'REST Decision API' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Playwire Desktop Video & App Monetization Portal
|
|
||||||
console.log('--- Inspecting Portal 2: Playwire Desktop Revenue Engine ---');
|
|
||||||
try {
|
|
||||||
await page.goto('https://www.playwire.com/contact-desktop-video-app-monetization', { timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '02_playwire_desktop_monetization.png') });
|
|
||||||
results.push({ name: 'Playwire Desktop', status: 'Inspected & Portal Captured', type: 'Desktop Programmatic Header Bidding', api: 'Playwire RAMP Engine' });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Playwire inspection error:', err.message);
|
|
||||||
results.push({ name: 'Playwire Desktop', status: 'Inspected', type: 'Desktop Programmatic', api: 'RAMP Engine' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Carbon Ads (BuySellAds)
|
|
||||||
console.log('--- Inspecting Portal 3: Carbon Ads ---');
|
|
||||||
try {
|
|
||||||
await page.goto('https://www.carbonads.net/', { timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '03_carbon_ads_home.png') });
|
|
||||||
results.push({ name: 'Carbon Ads', status: 'Inspected', type: 'Tech Native Single-Unit', api: 'Carbon Native JSON' });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Carbon Ads error:', err.message);
|
|
||||||
results.push({ name: 'Carbon Ads', status: 'Inspected', type: 'Tech Native', api: 'Carbon Native' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Unity Ads & LevelPlay
|
|
||||||
console.log('--- Inspecting Portal 4: Unity Ads & LevelPlay ---');
|
|
||||||
try {
|
|
||||||
await page.goto('https://unity.com/products/unity-ads', { timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '04_unity_ads_landing.png') });
|
|
||||||
results.push({ name: 'Unity Ads', status: 'Inspected', type: 'Rewarded Video & Mediation', api: 'Unity LevelPlay SDK' });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Unity Ads error:', err.message);
|
|
||||||
results.push({ name: 'Unity Ads', status: 'Inspected', type: 'Rewarded Video', api: 'LevelPlay SDK' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. AppLovin MAX
|
|
||||||
console.log('--- Inspecting Portal 5: AppLovin MAX ---');
|
|
||||||
try {
|
|
||||||
await page.goto('https://www.applovin.com/max/', { timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '05_applovin_max_landing.png') });
|
|
||||||
results.push({ name: 'AppLovin MAX', status: 'Inspected', type: 'Real-time In-App Bidding', api: 'MAX Mediation Adapter' });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('AppLovin error:', err.message);
|
|
||||||
results.push({ name: 'AppLovin MAX', status: 'Inspected', type: 'In-App Bidding', api: 'MAX Adapter' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. PubMatic OpenWrap
|
|
||||||
console.log('--- Inspecting Portal 6: PubMatic ---');
|
|
||||||
try {
|
|
||||||
await page.goto('https://pubmatic.com/', { timeout: 30000 });
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '06_pubmatic_landing.png') });
|
|
||||||
results.push({ name: 'PubMatic', status: 'Inspected', type: 'Programmatic Header Bidding SSP', api: 'OpenWrap Prebid' });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('PubMatic error:', err.message);
|
|
||||||
results.push({ name: 'PubMatic', status: 'Inspected', type: 'SSP Header Bidding', api: 'OpenWrap' });
|
|
||||||
}
|
|
||||||
|
|
||||||
await browser.close();
|
|
||||||
console.log('--- Portal Inspection Results ---');
|
|
||||||
console.log(JSON.stringify(results, null, 2));
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(SCREENSHOT_DIR, 'portal_inspection_summary.json'),
|
|
||||||
JSON.stringify(results, null, 2),
|
|
||||||
'utf-8'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
inspectAndRegisterPortals().catch((err) => {
|
|
||||||
console.error('Portal script failed:', err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue