diff --git a/tmp-active.mjs b/tmp-active.mjs new file mode 100644 index 0000000..3298504 --- /dev/null +++ b/tmp-active.mjs @@ -0,0 +1,64 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 测试所有 6 个标签 + const labels = ['碳核算平台', '碳交易平台', '碳认证机构', '碳金融服务', '碳技术咨询', '更多能力']; + const expectedAnchors = ['content-1', 'content-3', 'content-2', 'content-4', 'content-5', null]; + + for (let i = 0; i < labels.length; i++) { + await page.locator('.capability-card').nth(i).click(); + await page.waitForFunction(() => location.href.includes('gxnlpt'), { timeout: 5000 }); + await page.waitForTimeout(2500); + + const data = await page.evaluate(() => { + const sideItems = document.querySelectorAll('.gxnlpt-side-item'); + const active = Array.from(sideItems).map((el, idx) => ({ + idx, text: el.textContent.trim(), active: el.classList.contains('is-active') + })).find(x => x.active); + const content1 = document.getElementById('content-1'); + const content2 = document.getElementById('content-2'); + const content3 = document.getElementById('content-3'); + const content4 = document.getElementById('content-4'); + const content5 = document.getElementById('content-5'); + const rects = {}; + for (const el of [content1, content2, content3, content4, content5]) { + if (el) rects[el.id] = Math.round(el.getBoundingClientRect().top); + } + return { + url: location.href, + scrollTop: document.querySelector('.content-wrap').scrollTop, + activeTab: active, + sectionTops: rects, + }; + }); + console.log(`[${labels[i]}]`, JSON.stringify(data)); + + // 回到首页 + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + } + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-capability-debug.mjs b/tmp-capability-debug.mjs new file mode 100644 index 0000000..5e5b026 --- /dev/null +++ b/tmp-capability-debug.mjs @@ -0,0 +1,67 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + page.on('pageerror', (e) => console.log('[pageerror]', e.message)); + page.on('console', (m) => { + const t = m.text(); + console.log(`[browser:${m.type()}]`, t); + }); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + console.log('home loaded'); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 "碳核算平台" + const cardIndex = 0; + await page.locator('.capability-card').nth(cardIndex).click(); + // 多等几秒看是否跳转 + await page.waitForTimeout(4000); + console.log('url:', page.url()); + + // 检查 router-view 内的内容 + const data = await page.evaluate(() => { + const outlet = document.querySelector('.portal-route-outlet'); + if (!outlet) return { hasOutlet: false }; + const child = outlet.firstElementChild; + return { + hasOutlet: true, + hasChild: !!child, + childTag: child ? child.tagName : null, + childClass: child ? child.className : null, + hasGongXingNeng: !!document.querySelector('.gxnlpt-shell'), + hasCapabilitySection: !!document.querySelector('.capability-section'), + hasContent1: !!document.getElementById('content-1'), + bodyText: (document.body.innerText || '').slice(0, 300), + }; + }); + console.log('data:', data); + + await page.screenshot({ path: 'tmp-debug.png', fullPage: false }); + + // 等待 5s 后再次检查 + await page.waitForTimeout(5000); + const data2 = await page.evaluate(() => ({ + hasGongXingNeng: !!document.querySelector('.gxnlpt-shell'), + hasCapabilitySection: !!document.querySelector('.capability-section'), + hasContent1: !!document.getElementById('content-1'), + url: location.href, + })); + console.log('data2:', data2); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-capability-test.mjs b/tmp-capability-test.mjs new file mode 100644 index 0000000..c6ec66f --- /dev/null +++ b/tmp-capability-test.mjs @@ -0,0 +1,93 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + page.on('console', (m) => { + const t = m.text(); + if (t.includes('anchor') || t.includes('Capability') || t.includes('section')) { + console.log('[browser]', t); + } + }); + // 1) 打开首页 + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + // 等到 capability 区域可见 + await page.waitForSelector('.capability-section', { timeout: 20000 }); + console.log('home loaded'); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 截图 home + await page.screenshot({ path: 'tmp-home.png', fullPage: false }); + + // 取各 capability 卡的文本 + const cards = await page.$$eval('.capability-card .capability-name', (els) => els.map((e) => e.textContent.trim())); + console.log('capability cards:', cards); + + // 点击 "碳核算平台" + const cardIndex = cards.indexOf('碳核算平台'); + console.log('clicking index', cardIndex); + await page.locator('.capability-card').nth(cardIndex).click(); + await page.waitForTimeout(2500); + console.log('after click url:', page.url()); + + // 等 section 出现 + const hasContent1 = await page.locator('#content-1').count(); + console.log('content-1 exists:', hasContent1); + if (hasContent1) { + const inView = await page.locator('#content-1').evaluate((el) => { + const r = el.getBoundingClientRect(); + return { top: r.top, bottom: r.bottom, vh: window.innerHeight }; + }); + console.log('content-1 rect after click:', inView); + } + + await page.screenshot({ path: 'tmp-gxnlpt-content-1.png', fullPage: false }); + + // 回到首页 + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 "碳认证机构" -> content-2 + const idx2 = cards.indexOf('碳认证机构'); + await page.locator('.capability-card').nth(idx2).click(); + await page.waitForTimeout(2500); + console.log('after click content-2 url:', page.url()); + const r2 = await page.locator('#content-2').evaluate((el) => { + const r = el.getBoundingClientRect(); + return { top: r.top, bottom: r.bottom }; + }); + console.log('content-2 rect after click:', r2); + + // 点击 "更多能力" + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + const moreIdx = cards.indexOf('更多能力'); + await page.locator('.capability-card').nth(moreIdx).click(); + await page.waitForTimeout(2000); + console.log('after click 更多能力 url:', page.url()); + await page.screenshot({ path: 'tmp-gxnlpt-more.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-debug2.mjs b/tmp-debug2.mjs new file mode 100644 index 0000000..fb9229d --- /dev/null +++ b/tmp-debug2.mjs @@ -0,0 +1,70 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(3500); + + // 查看 DOM 状态 + const data = await page.evaluate(() => { + const out = {}; + const wrap = document.querySelector('.content-wrap'); + out.wrapScrollTop = wrap ? wrap.scrollTop : null; + out.wrapScrollHeight = wrap ? wrap.scrollHeight : null; + out.wrapClientHeight = wrap ? wrap.clientHeight : null; + out.wrapClasses = wrap ? wrap.className : null; + out.wrapStyleHeight = wrap ? getComputedStyle(wrap).height : null; + out.htmlClasses = document.documentElement.className; + out.htmlData = (function() { + const r = document.documentElement.getBoundingClientRect(); + return { width: r.width, height: r.height }; + })(); + const root = document.documentElement; + out.homeFigmaScale = getComputedStyle(root).getPropertyValue('--home-figma-scale'); + out.portalShellMinDesignHeight = getComputedStyle(root).getPropertyValue('--portal-shell-min-design-height'); + out.portalLandingFirstScreenHeight = getComputedStyle(root).getPropertyValue('--portal-landing-first-screen-height'); + out.pageNavHeight = getComputedStyle(root).getPropertyValue('--page-nav-height'); + + const outlet = document.querySelector('.portal-route-outlet'); + out.outletChildren = outlet ? outlet.children.length : null; + const firstChild = outlet && outlet.firstElementChild; + out.firstChildClass = firstChild ? firstChild.className : null; + out.firstChildBoundingRect = firstChild ? (function() { + const r = firstChild.getBoundingClientRect(); + return { top: r.top, left: r.left, width: r.width, height: r.height }; + })() : null; + out.firstChildStyle = firstChild ? firstChild.getAttribute('style') : null; + + // 找 content-1 + const c1 = document.getElementById('content-1'); + out.content1Rect = c1 ? (function() { + const r = c1.getBoundingClientRect(); + return { top: r.top, left: r.left, width: r.width, height: r.height }; + })() : null; + return out; + }); + console.log(JSON.stringify(data, null, 2)); + + // 不截图 + // await page.screenshot({ path: 'tmp-debug2.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-direct-1.png b/tmp-direct-1.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-direct-1.png differ diff --git a/tmp-direct-2.png b/tmp-direct-2.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-direct-2.png differ diff --git a/tmp-elementfrom.mjs b/tmp-elementfrom.mjs new file mode 100644 index 0000000..5d87a33 --- /dev/null +++ b/tmp-elementfrom.mjs @@ -0,0 +1,41 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(3500); + + // 检查视口不同位置是什么元素 + const points = await page.evaluate(() => { + const results = []; + const pts = [[720, 100], [720, 300], [720, 500], [720, 700], [200, 200], [1200, 200], [720, 850]]; + for (const [x, y] of pts) { + const els = document.elementsFromPoint(x, y); + results.push({ x, y, els: els.slice(0, 5).map((el) => ({ tag: el.tagName, cls: (el.className || '').slice(0, 80), id: el.id })) }); + } + return results; + }); + console.log('points:'); + for (const p of points) { + console.log(` (${p.x},${p.y}):`, JSON.stringify(p.els)); + } + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-final-1.png b/tmp-final-1.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-final-1.png differ diff --git a/tmp-final-2.png b/tmp-final-2.png new file mode 100644 index 0000000..db1a147 Binary files /dev/null and b/tmp-final-2.png differ diff --git a/tmp-final.mjs b/tmp-final.mjs new file mode 100644 index 0000000..6ab6a3b --- /dev/null +++ b/tmp-final.mjs @@ -0,0 +1,46 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 1 }); + const page = await ctx.newPage(); + + // 不使用 keep-alive + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 用 evaluate 在点击前修改 router 行为,禁用 keep-alive + // 不行;改用:点击后等久一点,确认 router 完成 + await page.locator('.capability-card').nth(0).click(); + // 等待 URL 变化 + await page.waitForFunction(() => location.href.includes('gxnlpt'), { timeout: 5000 }); + // 等待 gxnlpt-page 真正在视口里 + await page.waitForFunction(() => { + const el = document.querySelector('.gxnlpt-page'); + if (!el) return false; + const r = el.getBoundingClientRect(); + return r.top >= -10 && r.top < 200; + }, { timeout: 5000 }); + await page.waitForTimeout(2000); + + // 截 viewport + await page.screenshot({ path: 'tmp-final-1.png', fullPage: false }); + + // 截元素 + const el = await page.locator('.gxnlpt-page').first(); + await el.screenshot({ path: 'tmp-final-2.png' }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-gxnlpt-content-1.png b/tmp-gxnlpt-content-1.png new file mode 100644 index 0000000..9bb1fac Binary files /dev/null and b/tmp-gxnlpt-content-1.png differ diff --git a/tmp-gxnlpt-el.png b/tmp-gxnlpt-el.png new file mode 100644 index 0000000..db1a147 Binary files /dev/null and b/tmp-gxnlpt-el.png differ diff --git a/tmp-gxnlpt-more.png b/tmp-gxnlpt-more.png new file mode 100644 index 0000000..32a0d31 Binary files /dev/null and b/tmp-gxnlpt-more.png differ diff --git a/tmp-home.png b/tmp-home.png new file mode 100644 index 0000000..029ef40 Binary files /dev/null and b/tmp-home.png differ diff --git a/tmp-no-keepalive.mjs b/tmp-no-keepalive.mjs new file mode 100644 index 0000000..78e0451 --- /dev/null +++ b/tmp-no-keepalive.mjs @@ -0,0 +1,50 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + // 模拟 真实用户使用:刷新一次后不依赖 keep-alive + // 第一次访问 gxnlpt + await page.goto(`${BASE}/view/mhzc/gxnlpt`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.gxnlpt-page', { timeout: 20000 }); + await page.waitForTimeout(1500); + + // 直接访问首页 + 点击, 不等待 keep-alive 命中 + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 "碳交易平台" + await page.locator('.capability-card').nth(1).click(); + await page.waitForFunction(() => location.href.includes('gxnlpt'), { timeout: 5000 }); + await page.waitForTimeout(2000); + + // 检查实际显示 + const data = await page.evaluate(() => { + const out = {}; + out.url = location.href; + out.scrollTop = document.querySelector('.content-wrap').scrollTop; + const sections = ['content-1', 'content-2', 'content-3', 'content-4', 'content-5'].map((id) => { + const el = document.getElementById(id); + return { id, top: el ? Math.round(el.getBoundingClientRect().top) : null }; + }); + out.sections = sections; + return out; + }); + console.log('after click 碳交易平台:', JSON.stringify(data, null, 2)); + + await page.screenshot({ path: 'tmp-no-keepalive.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-pix-1.png b/tmp-pix-1.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-pix-1.png differ diff --git a/tmp-pix-2.png b/tmp-pix-2.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-pix-2.png differ diff --git a/tmp-pix-3.png b/tmp-pix-3.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-pix-3.png differ diff --git a/tmp-pix-4.png b/tmp-pix-4.png new file mode 100644 index 0000000..db1a147 Binary files /dev/null and b/tmp-pix-4.png differ diff --git a/tmp-pix-5.png b/tmp-pix-5.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-pix-5.png differ diff --git a/tmp-pixel.mjs b/tmp-pixel.mjs new file mode 100644 index 0000000..1dd1e6b --- /dev/null +++ b/tmp-pixel.mjs @@ -0,0 +1,57 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(3500); + + // 视口截图 + await page.screenshot({ path: 'tmp-pix-1.png', fullPage: false }); + + // 用 dom snapshot(用 canvas 截屏) + await page.evaluate(() => { + return new Promise((resolve) => { + // 强制重排 + document.body.offsetHeight; + resolve(); + }); + }); + await page.waitForTimeout(500); + await page.screenshot({ path: 'tmp-pix-2.png', fullPage: false }); + + // 显式滚动到顶部 + await page.evaluate(() => { + const w = document.querySelector('.content-wrap'); + if (w) w.scrollTop = 0; + }); + await page.waitForTimeout(500); + await page.screenshot({ path: 'tmp-pix-3.png', fullPage: false }); + + // 直接用 html2canvas 方式:通过截图 element 方式 + const gxnlptEl = await page.locator('.gxnlpt-page').first(); + await gxnlptEl.screenshot({ path: 'tmp-pix-4.png' }); + + // 强制重排 + 再次截图 + await page.evaluate(() => window.dispatchEvent(new Event('resize'))); + await page.waitForTimeout(500); + await page.screenshot({ path: 'tmp-pix-5.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-snap-body.png b/tmp-snap-body.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-snap-body.png differ diff --git a/tmp-snap-viewport.png b/tmp-snap-viewport.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-snap-viewport.png differ diff --git a/tmp-snap.mjs b/tmp-snap.mjs new file mode 100644 index 0000000..10cade0 --- /dev/null +++ b/tmp-snap.mjs @@ -0,0 +1,54 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(3500); + + // 给 gxnlpt-page 元素截图 + const gxnlptEl = await page.locator('.gxnlpt-page').first(); + await gxnlptEl.screenshot({ path: 'tmp-gxnlpt-el.png' }); + + // 给视口截图 + await page.screenshot({ path: 'tmp-snap-viewport.png', fullPage: false }); + + // 给 body 截图 + const body = await page.locator('body').first(); + await body.screenshot({ path: 'tmp-snap-body.png' }); + + // 检查 gxnlpt-page 的可见性 + const r = await gxnlptEl.evaluate((el) => { + const rect = el.getBoundingClientRect(); + const style = getComputedStyle(el); + return { + rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height, bottom: rect.bottom, right: rect.right }, + display: style.display, + visibility: style.visibility, + opacity: style.opacity, + zIndex: style.zIndex, + transform: style.transform, + transformOrigin: style.transformOrigin, + position: style.position, + }; + }); + console.log('gxnlpt:', JSON.stringify(r, null, 2)); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-snap2.mjs b/tmp-snap2.mjs new file mode 100644 index 0000000..91da258 --- /dev/null +++ b/tmp-snap2.mjs @@ -0,0 +1,42 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + // 直接访问 gxnlpt?anchor=content-1(不要先访问 home),看看非 keep-alive 场景是否正常 + await page.goto(`${BASE}/view/mhzc/gxnlpt?anchor=content-1`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.gxnlpt-page', { timeout: 20000 }); + await page.waitForTimeout(3500); + + await page.screenshot({ path: 'tmp-direct-1.png', fullPage: false }); + + // 滚动到顶部 + await page.evaluate(() => { + const w = document.querySelector('.content-wrap'); + if (w) w.scrollTop = 0; + }); + await page.waitForTimeout(500); + await page.screenshot({ path: 'tmp-direct-2.png', fullPage: false }); + + // 在视口顶部 evaluate 一下 + const data = await page.evaluate(() => { + const outlet = document.querySelector('.portal-route-outlet'); + const child = outlet && outlet.firstElementChild; + return { + outletChildCount: outlet ? outlet.children.length : 0, + childClass: child && child.className, + contentWrapScrollTop: document.querySelector('.content-wrap').scrollTop, + url: location.href, + }; + }); + console.log('data:', JSON.stringify(data)); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-zoom-1-home.png b/tmp-zoom-1-home.png new file mode 100644 index 0000000..44feda9 Binary files /dev/null and b/tmp-zoom-1-home.png differ diff --git a/tmp-zoom-2-after-click.png b/tmp-zoom-2-after-click.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-zoom-2-after-click.png differ diff --git a/tmp-zoom-3-top.png b/tmp-zoom-3-top.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-zoom-3-top.png differ diff --git a/tmp-zoom.mjs b/tmp-zoom.mjs new file mode 100644 index 0000000..0ac231a --- /dev/null +++ b/tmp-zoom.mjs @@ -0,0 +1,39 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 截图 home capability + await page.screenshot({ path: 'tmp-zoom-1-home.png', fullPage: false }); + + // 点击 "碳核算平台" + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(3000); + console.log('url:', page.url()); + + await page.screenshot({ path: 'tmp-zoom-2-after-click.png', fullPage: false }); + + // 滚动到顶部再截图 + await page.evaluate(() => window.scrollTo(0, 0)); + await page.waitForTimeout(800); + await page.screenshot({ path: 'tmp-zoom-3-top.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-zoom2.mjs b/tmp-zoom2.mjs new file mode 100644 index 0000000..d5e0990 --- /dev/null +++ b/tmp-zoom2.mjs @@ -0,0 +1,75 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 "碳核算平台" + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(3000); + console.log('url:', page.url()); + + // 检查实际 DOM + const data = await page.evaluate(() => { + const outlet = document.querySelector('.portal-route-outlet'); + const child = outlet && outlet.firstElementChild; + const sidebar = !!document.querySelector('.gxnlpt-sidebar'); + return { + hasOutlet: !!outlet, + hasChild: !!child, + childClass: child ? child.className : null, + hasGongXingNeng: !!document.querySelector('.gxnlpt-shell'), + hasGxnlptSidebar: sidebar, + hasContent1: !!document.getElementById('content-1'), + activeSection: (function() { + const els = document.querySelectorAll('[id^="content-"]'); + const inView = []; + els.forEach((el) => { + const r = el.getBoundingClientRect(); + if (r.top >= -50 && r.top < 800) { + inView.push({ id: el.id, top: Math.round(r.top) }); + } + }); + return inView; + })(), + visibleViewport: (function() { + const els = document.querySelectorAll('.gxnlpt-block, [id^="content-"], .gxnlpt-side-nav, .gxnlpt-sidebar'); + const all = []; + for (const el of els) { + const r = el.getBoundingClientRect(); + if (r.width === 0 || r.height === 0) continue; + all.push({ + tag: el.tagName, + cls: el.className && el.className.slice(0, 60), + id: el.id, + top: Math.round(r.top), + bottom: Math.round(r.bottom), + left: Math.round(r.left), + }); + } + return all; + })(), + }; + }); + console.log(JSON.stringify(data, null, 2)); + + await page.screenshot({ path: 'tmp-zoom2.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-zoom2.png b/tmp-zoom2.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-zoom2.png differ diff --git a/tmp-zoom3-no-eval.png b/tmp-zoom3-no-eval.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-zoom3-no-eval.png differ diff --git a/tmp-zoom3.mjs b/tmp-zoom3.mjs new file mode 100644 index 0000000..434f000 --- /dev/null +++ b/tmp-zoom3.mjs @@ -0,0 +1,32 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 "碳核算平台" + await page.locator('.capability-card').nth(0).click(); + await page.waitForTimeout(5000); + console.log('url:', page.url()); + + // 不调用 evaluate,直接截图 + await page.screenshot({ path: 'tmp-zoom3-no-eval.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-zoom4.mjs b/tmp-zoom4.mjs new file mode 100644 index 0000000..55e1d4d --- /dev/null +++ b/tmp-zoom4.mjs @@ -0,0 +1,49 @@ +import { chromium } from 'playwright'; + +const BASE = 'http://localhost:9027'; + +(async () => { + const browser = await chromium.launch(); + const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const page = await ctx.newPage(); + + await page.goto(`${BASE}/view/mhzc/home`, { waitUntil: 'networkidle', timeout: 30000 }); + await page.waitForSelector('.capability-section', { timeout: 20000 }); + + // 滚动到 capability 区域 + await page.evaluate(() => { + const el = document.getElementById('section-capability'); + if (el) el.scrollIntoView({ behavior: 'instant', block: 'start' }); + }); + await page.waitForTimeout(800); + + // 点击 "碳核算平台" + await page.locator('.capability-card').nth(0).click(); + + // 不停截图 + for (let i = 0; i < 10; i++) { + await page.waitForTimeout(1000); + const info = await page.evaluate(() => { + const contentWrap = document.querySelector('.content-wrap'); + const gxnlptSidebar = document.querySelector('.gxnlpt-sidebar'); + const home = document.querySelector('.capability-section'); + const content1 = document.getElementById('content-1'); + return { + url: location.href, + scrollTop: contentWrap ? contentWrap.scrollTop : null, + scrollHeight: contentWrap ? contentWrap.scrollHeight : null, + hasGxnlptSidebar: !!gxnlptSidebar, + hasHome: !!home, + content1Top: content1 ? Math.round(content1.getBoundingClientRect().top) : null, + }; + }); + console.log(`t=${i+1}s`, JSON.stringify(info)); + } + + await page.screenshot({ path: 'tmp-zoom4.png', fullPage: false }); + + await browser.close(); +})().catch((e) => { + console.error('TEST ERROR', e); + process.exit(1); +}); diff --git a/tmp-zoom4.png b/tmp-zoom4.png new file mode 100644 index 0000000..91d63f7 Binary files /dev/null and b/tmp-zoom4.png differ diff --git a/txw-mhzc-web/src/pages/index/router/routes.js b/txw-mhzc-web/src/pages/index/router/routes.js index c710b4d..0a185ed 100644 --- a/txw-mhzc-web/src/pages/index/router/routes.js +++ b/txw-mhzc-web/src/pages/index/router/routes.js @@ -314,7 +314,7 @@ export default [ title: '数据列表', isShowSideBar: false, hasHome: true, - breadCrumbs: [{ title: '首页', to: '/home' }, { title: '服务中心', to: '' }, { title: '碳数据市场', to: '/fwscsjlbc' }], + breadCrumbs: [{ title: '首页', to: '/home' }, { title: '服务中心', to: '' }, { title: '碳数据市场', to: '/tsjsc' }], disableBack: true, }, }, diff --git a/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue b/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue index 5d1984d..6f4fc38 100644 --- a/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue +++ b/txw-mhzc-web/src/pages/index/views/fwsc/fwsc.vue @@ -930,7 +930,7 @@ export default { .price-value { font-size: 20px; font-weight: 600; - color: #FF4D4F; + color: #2E7D32; } .price-unit { diff --git a/txw-mhzc-web/src/pages/index/views/fwsc/sjlbc.vue b/txw-mhzc-web/src/pages/index/views/fwsc/sjlbc.vue index 8a3c924..94b02fb 100644 --- a/txw-mhzc-web/src/pages/index/views/fwsc/sjlbc.vue +++ b/txw-mhzc-web/src/pages/index/views/fwsc/sjlbc.vue @@ -320,7 +320,7 @@ export default { .breadcrumb-box { display: flex; align-items: center; - width: 100%; + width: 83%; max-width: 1400px; padding: 20px 20px 0; margin: 0 auto; @@ -354,7 +354,7 @@ export default { display: flex; align-items: flex-start; justify-content: space-between; - width: 100%; + width: 81%; max-width: 1400px; padding: 24px; margin: 16px auto 0; diff --git a/txw-mhzc-web/src/pages/index/views/fwsc/sjsc.vue b/txw-mhzc-web/src/pages/index/views/fwsc/sjsc.vue index af9001e..fdbc52e 100644 --- a/txw-mhzc-web/src/pages/index/views/fwsc/sjsc.vue +++ b/txw-mhzc-web/src/pages/index/views/fwsc/sjsc.vue @@ -36,11 +36,6 @@