Files
msh-system/docs/Testing/iframe-testing-workaround.md
scottpan 4be53dcd1b feat: 集成 KieAI 服务,移除 models-integration 子项目
- 添加 Gemini 2.5 Flash 对话接口(流式+非流式)
- 添加 NanoBanana 图像生成/编辑接口
- 添加 Sora2 视频生成接口(文生视频、图生视频、去水印)
- 移除 models-integration 子项目(功能已迁移至主后端)
- 新增测试文档和 Playwright E2E 配置
- 更新前端页面和 API 接口
- 更新后端配置和日志处理
2026-03-03 15:33:50 +08:00

10 KiB

Working Around Iframe Testing Limitations

Problem Statement

The H5 application uses an iframe-based wrapper (/static/html/pc.html) which prevents automated browser testing tools from interacting with the actual application content. The iframe loads the mobile app at / inside it, creating an isolated browsing context.

Architecture Diagram

┌─────────────────────────────────────────┐
│ http://localhost:8080/static/html/pc.html │
│ ┌─────────────────────────────────────┐ │
│ │  <iframe src="/">                   │ │
│ │  ┌───────────────────────────────┐  │ │
│ │  │ Actual H5 App                 │  │ │
│ │  │ (慢生活营养专家)                │  │ │
│ │  │                               │  │ │
│ │  │ - User Card                   │  │ │
│ │  │ - Function Cards              │  │ │
│ │  │ - Navigation                  │  │ │
│ │  └───────────────────────────────┘  │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘

Browser Tools CAN access: PC wrapper (outer page)
Browser Tools CANNOT access: Iframe content (actual app)

Why This Happens

From /msh_single_uniapp/static/html/pc.html:

<iframe src="/" id="iframe"></iframe>

The pc.html wrapper:

  1. Detects screen width
  2. If width > 450px: Shows centered iframe with border (PC view)
  3. If width ≤ 420px: Redirects to / (but still loads through router)
  4. Sets window.isPC = true flag

Current Limitations

What Works

  • Page navigation (can change URL)
  • Screenshot capture (visual verification)
  • Network monitoring (API calls visible)
  • Console log reading (errors visible)
  • Page load timing

What Doesn't Work

  • Element clicking (no refs inside iframe)
  • Form input (no access to input fields)
  • Text selection (isolated context)
  • Element attribute reading (no refs)
  • Hover interactions

Solutions & Workarounds

Solution 1: Manual Testing (Current Approach)

Status: Implemented

Use the comprehensive manual testing checklist:

  • /docs/Testing/manual-testing-checklist.md

Pros:

  • Works immediately
  • No code changes required
  • Can test all features
  • Human verification of UX

Cons:

  • Time-consuming
  • Not reproducible
  • Human error possible
  • Cannot automate regression tests

Solution 2: Direct H5 Access (Dev Environment)

Status: 🔶 Recommended for Testing

Step A: Modify pc.html for Testing

Create a test version that bypasses iframe:

// Add to pc.html temporarily
if (window.location.search.includes('direct=true')) {
  window.location.href = '/';
}

Then access: http://localhost:8080/static/html/pc.html?direct=true

Step B: Access Root Directly with Mobile User-Agent

The app routing logic checks for mobile devices. Browser tools can spoof user-agent:

// In browser console before navigation:
Object.defineProperty(navigator, 'userAgent', {
  get: function () { 
    return 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)';
  }
});

Then navigate to http://localhost:8080/

Step C: Modify Vue Router for Test Mode

Add a query parameter to bypass PC detection:

In your router configuration or App.vue:

// If ?test=true in URL, don't redirect to pc.html
if (this.$route.query.test === 'true') {
  // Stay on current page
}

Access: http://localhost:8080/?test=true


Solution 3: E2E Framework with Iframe Support

Status: 📋 Future Implementation

Option A: Playwright

// Playwright can switch to iframe context
const page = await browser.newPage();
await page.goto('http://localhost:8080');

// Switch to iframe
const iframe = page.frameLocator('#iframe');
await iframe.locator('.login-button').click();

Option B: Cypress with iframe plugin

// Install: npm install -D cypress-iframe
cy.visit('http://localhost:8080');
cy.frameLoaded('#iframe');
cy.iframe().find('.login-button').click();

Option C: Puppeteer

const page = await browser.newPage();
await page.goto('http://localhost:8080');

// Get iframe
const frameHandle = await page.$('#iframe');
const frame = await frameHandle.contentFrame();
await frame.click('.login-button');

Solution 4: Remove Iframe Wrapper (Architecture Change)

Status: 🎯 Long-term Recommendation

Current Architecture:

User → localhost:8080 → pc.html (checks screen size) → iframe src="/"
                                                        ↓
                                                  Actual H5 App

Proposed Architecture:

User → localhost:8080 → Direct H5 App
       (CSS media queries handle responsive design)

Benefits:

  • Enables automated testing
  • Better performance (no iframe overhead)
  • Simpler architecture
  • Better SEO
  • Easier debugging

Changes Required:

  1. Remove pc.html wrapper
  2. Use CSS media queries for responsive design:
/* Instead of iframe with fixed size */
@media screen and (min-width: 450px) {
  .mobile-app {
    max-width: 375px;
    margin: 0 auto;
    border: 1px solid #f5f5f5;
    border-radius: 4px;
  }
}
  1. Update build configuration:
// In vue.config.js or similar
publicPath: '/',
// Remove redirect logic

Implementation Estimate: 2-4 hours


Phase 1: Current (Manual Testing)

  • Use manual testing checklist
  • Document all findings
  • Capture screenshots
  • ~2-3 hours of testing

Phase 2: Quick Win (Direct Access)

  • Implement Solution 2 (query parameter bypass)
  • Enable automated testing for critical paths
  • ~1 hour implementation
  • Saves ~10 hours/week in testing

Phase 3: Proper Tooling (E2E Framework)

  • Set up Playwright or Cypress with iframe support
  • Create automated test suite
  • ~1 week implementation
  • Full regression coverage

Phase 4: Architecture Improvement (Remove Iframe)

  • Refactor to remove iframe wrapper
  • Use responsive CSS instead
  • ~1 day implementation
  • Permanent fix, enables all testing tools

Temporary Testing Script

For immediate testing needs, create this script:

File: test-helpers/direct-access.js

// Run this in browser console to enable direct testing
(function() {
  // Method 1: Remove iframe and show content directly
  const iframe = document.getElementById('iframe');
  if (iframe) {
    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
    document.body.innerHTML = iframeDoc.body.innerHTML;
    
    // Copy styles
    const iframeStyles = iframeDoc.getElementsByTagName('style');
    for (let style of iframeStyles) {
      document.head.appendChild(style.cloneNode(true));
    }
    
    console.log('✅ Iframe content extracted. You can now test directly.');
  }
  
  // Method 2: Add test hooks
  window.testMode = true;
  window.getIframeDoc = () => {
    return iframe.contentDocument || iframe.contentWindow.document;
  };
  
  console.log('✅ Test helpers loaded. Use window.getIframeDoc() to access iframe.');
})();

Usage:

  1. Open browser DevTools
  2. Paste script in console
  3. Press Enter
  4. Content now accessible for testing

Testing Without Iframe Access

Approach 1: API Testing

Since network requests are visible, test APIs directly:

// Test login API
fetch('http://127.0.0.1:20822/api/front/login/mobile', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    phone: '18621813282',
    password: 'A123456'
  })
})
.then(r => r.json())
.then(console.log);

Approach 2: Visual Testing

Use screenshot comparison tools:

  1. Take screenshot of expected state
  2. Take screenshot after changes
  3. Compare images using tools like:
    • pixelmatch
    • looks-same
    • BackstopJS

Approach 3: Network Monitoring

Verify functionality by monitoring network calls:

  1. User clicks button
  2. Check if correct API called
  3. Verify response
  4. Check if UI updates (via screenshot)

Implementation Priority

High Priority (This Week)

  1. Complete manual testing
  2. Fix known configuration issue
  3. Document manual test results

Medium Priority (This Month)

  1. 📋 Implement Solution 2 (direct access for testing)
  2. 📋 Set up API testing suite
  3. 📋 Visual regression testing setup

Low Priority (This Quarter)

  1. 📋 Evaluate E2E framework (Playwright vs Cypress)
  2. 📋 Consider architecture refactoring
  3. 📋 Implement automated test suite

Questions & Answers

Q: Why does the app use an iframe? A: To provide a centered mobile view on desktop browsers while maintaining the mobile H5 codebase. It's a common pattern for mobile-first apps.

Q: Can I just disable the iframe? A: Yes, but it requires code changes. See Solution 4 above.

Q: Will removing the iframe break anything? A: No, if done properly. The iframe is just a container. The app logic is independent.

Q: What's the fastest way to enable automated testing? A: Implement Solution 2 (query parameter to bypass iframe). Takes ~1 hour, enables all browser testing tools.

Q: Should we always use iframes? A: No. Modern responsive design with CSS media queries is preferred. Iframes add complexity and testing difficulty.


Resources

Documentation

Tools

Testing Strategies


Last Updated: March 2, 2026
Status: Documented
Recommended Action: Implement Solution 2 for immediate testing needs