const { chromium } = require('playwright'); const fs = require('fs'); (async () => { const browser = await chromium.launch({ headless: true // 👈 Windows建议先开界面调试 }); // 👇 关键就在这里 let context = null if (fs.existsSync('state.json')) { console.log('✅ state.json 存在'); context = await browser.newContext({ storageState: 'state.json', locale: "zh-CN" }); } else { console.log('❌ state.json 不存在'); context = await browser.newContext({ locale: "zh-CN" }) } const page = await context.newPage(); await page.goto('https://gitcode.com/setting/points'); await page.waitForTimeout(5000); const isLogin = await page.locator('.g-user-avatar').isVisible(); if (isLogin) { console.log('✅ 已登录'); runTasks(page) } else { console.log('❌ 未登录'); await page.getByText('密码登录').click(); await page.getByPlaceholder('请填写手机号/用户名/邮箱').fill('15623979816'); await page.getByPlaceholder('请填写密码').fill('Zzy1995115'); await page.getByText('登录或注册完成代表你同意').click(); await page.getByText('我同意将账号、组织、仓库等信息提供给AtomGit进行 ').click(); await page.locator('button:has-text("登 录")').click(); await page.waitForTimeout(1000); await context.storageState({ path: 'state.json' }); runTasks(page) } })(); async function runTasks(page) { console.log('✅ 开始寻找每日任务'); const tasks = await page.locator('.novice-task-item-box').all(); console.log('✅ 共找到' + tasks.length + '个每日任务'); for (const task of tasks) { const title = await task.locator('.task-card-title__label-text').innerText(); if (title.includes("更新项目")) { const taskStat = await taskIsCompleted(task) if (!taskStat) { await doUpdateProject(page) } } else if (title.includes("每日分享")) { const taskStat = await taskIsCompleted(task) if (!taskStat) { await dailyShare(task, page) } } else if (title.includes("每日签到")) { const taskStat = await taskIsCompleted(task) if (!taskStat) { await dailyCheckInTask(task, page) } } else if (title.includes("查看热门")) { const taskStat = await taskIsCompleted(task) if (!taskStat) { await dailyViewTrending(task, page) } } else if (title.includes("每日Star")) { const taskStat = await taskIsCompleted(task) if (!taskStat) { await dailyViewStar(task, page) } } } await page.waitForTimeout(2000); await page.reload({ waitUntil: "domcontentloaded" }); await page.waitForTimeout(2000); await page.locator('button.pickup-btn:has-text("一键领取")').click(); } async function taskIsCompleted(task) { const taskEnd = await task.locator('button:has-text("领取奖励")').count() > 0 if (taskEnd) { task.locator('button:has-text("领取奖励")').click() return true } const isCompleted = await task.locator('.completed').count() > 0 if (isCompleted) { console.log('✅ 已完成,跳过'); return true } return false } async function doUpdateProject(page) { console.log('👉 执行项目更新'); const context = page.context(); const newPage = await context.newPage(); await newPage.goto('https://gitcode.com/fzxlzy/test/edit/main/testjpgp11'); // 你可以自己补逻辑 const frame = newPage.frameLocator('#codeartside'); // 1️⃣ 点击编辑器 await frame.locator('.monaco-editor').click({ position: { x: 200, y: 100 } }); // 2️⃣ 把光标移动到末尾(关键!) await newPage.keyboard.press('Control+End'); // 3️⃣ 追加内容 await newPage.keyboard.type(`\n测试图片生成功能 11 22 33`, { delay: 50 }); // 等按钮出现 await newPage.locator('button:has-text("提交修改")').click(); await page.waitForTimeout(1000); const submitButton = newPage.locator('button:has-text("提交修改")').nth(1); // 0 是页面按钮,1 是弹框按钮 await submitButton.click(); await newPage.waitForTimeout(500); await newPage.close(); } async function dailyShare(task, page) { // 等待新页面打开 const [newPage] = await Promise.all([ page.context().waitForEvent('page'), // 等待新页面事件 task.locator('.toComplete').click() ]); // 点击第一个 await newPage.waitForTimeout(1000); await newPage.locator('.immediately-invite-btn').nth(0).click(); await newPage.waitForTimeout(2000); await newPage.close(); } async function dailyCheckInTask(task, page) { await page.waitForTimeout(1000); task.locator('button:has-text("签到")').click() await page.waitForTimeout(1000); } async function dailyViewTrending(task, page) { // 等待新页面打开 const [newPage] = await Promise.all([ page.context().waitForEvent('page'), // 等待新页面事件 task.locator('.toComplete').click() ]) await newPage.waitForSelector('.hot-selection .recommend-card'); // 获取第一个热门项目卡片 const firstHotProjectCard = await newPage.$('.hot-selection .recommend-card'); await newPage.waitForTimeout(1000); // 点击它 const [newPage2] = await Promise.all([ newPage.context().waitForEvent('page'), // 等待新页面事件 await firstHotProjectCard.click() ]) await newPage2.waitForTimeout(2000); newPage2.close() newPage.close() } async function dailyViewStar(task, page) { // 等待新页面打开 const [newPage] = await Promise.all([ page.context().waitForEvent('page'), // 等待新页面事件 task.locator('.toComplete').click() ]) // 等待元素出现在 DOM(不要用 visible,容易超时) await newPage.waitForSelector('.hot-selection-list a.recommend-card', { state: 'attached' }); const cards = newPage.locator('.hot-selection-list a.recommend-card'); const count = await cards.count(); console.log("热门项目数量:", count); if (count === 0) { throw new Error("没有找到热门项目"); } await newPage.waitForTimeout(2000); // 随机选一个 const index = Math.floor(Math.random() * count); console.log("随机选择 index:", index); // 点击并捕获新 tab const [newPage2] = await Promise.all([ newPage.context().waitForEvent('page'), cards.nth(index).click() ]); // 等待 Star 按钮出现 const starBtn = newPage2.locator('#repo-header-tab .status-btn').filter({ hasText: 'Star' }).nth(1); await newPage2.waitForTimeout(2000); await starBtn.waitFor({ state: 'visible' }); // 判断是否已 Starred const text = await starBtn.innerText(); await newPage2.waitForTimeout(2000); if (text.includes('Starred')) { // 已经 Starred -> 先取消 await starBtn.click(); // 等待变回 Star await newPage2.waitForTimeout(500); } await starBtn.click(); await newPage2.waitForTimeout(2000); newPage2.close() newPage.close() }