Plainer HTML Testbed

このページにある要素はすべてキャプチャできるはずなので、 キャプチャできない or キャプチャは出来ているが編集/閲覧時に表示されない 場合はデグレの可能性があります。

このページ 1 枚をキャプチャすれば、下記「専用ページ」以外のパターンを網羅できます。 各ケースの 緑の枠 がキャプチャデータ閲覧時の正しい状態、 黄の枠 は「このページを直接開いた状態では崩れて見えるのが正常」なケースです。

専用ページ

以下はこのページに収録していないケース。ページ全体の構造に依存する、またはこのページに混ぜると他のケースを壊すため、単独のページで検証する。

キャプチャ検証(単独ページでキャプチャする)

自動巡回キャプチャ auto-capture/ 連番ページの相互リンク、URL 同一視、ログインパターン、SPA 複数ページ間の遷移そのものが検証対象
frameset / frame 要素 frameset/ 基本(ネスト) frame 内 PDF frame 内 blob frameset は body の代わりにページ全体を構成する
Quirks モード quirks/ DOCTYPE なし(BackCompat)での描画 トップ文書に DOCTYPE が無いことが条件
前面レイヤーに隠れた要素 overlay_patterns/ モーダル / メニュー / ドロワーの裏の要素を編集画面で選択できるか(6パターン) 全画面オーバーレイや body の pointer-events:none でページ全体を覆う
折り畳みサイドメニュー fold_nav/ fold 内リンクが pageLink に誤設定されないか 自動キャプチャのページ遷移と全画面アプリレイアウトが対象
焼き付き座標 baked_geometry/ 開いたポッパー JS 配置の fixed ビューア サイトの JS がキャプチャ時のビューポート幅で計算した px 座標をインライン style に焼き込むため、キャプチャ幅を固定した単独ページで検証する
Wijmo FlexGrid wijmo/ 仮想スクロール・固定列のグリッド 評価版 CDN の透かしがページ全体に被さる

キャプチャできない構造(既知の非対応)

HTML モードでキャプチャできない uncapturable/html-mode.html ShadowDOM のスタイルが外に漏れる / display:grid で無理やり表示している不正な table
JSON モードでキャプチャできない uncapturable/json-mode.html iframe と ShadowDOM の交互ネスト
全モードでキャプチャできない uncapturable/all-mode.html pdf.js の ?file なし埋め込み / video / audio 混ぜるとスタイル漏れ等でこのページの判定まで崩れる

デモ・埋め込み用(キャプチャ検証ではない)

サンプルダッシュボード sample_dashboard/ 操作説明などに使うダッシュボード
SaaS サイト saas_site/ デモ埋め込みテスト用の複数ページサイト
メディアフォーム form/form.html PLAINER に埋め込み、入力値を postMessage で親へ送る

VRT fixture 採取元(内容はこのページにも収録)

CSS ポジション css/position.html このページでは position / overflow / スクロール
overflow / スクロール css/overflow.html このページでは position / overflow / スクロール
ネスト iframe 内の Web Components web_components_in_iframe.html このページでは iframe plainer-backend の配信ページ VRT が単独ページとしてキャプチャしている

iframe

多層 iframe(src / srcdoc)

src形式(4層)
srcdoc形式(4層)

src形式・srcdoc形式とも 1〜4 層目のテキストと入れ子の枠がすべて表示される(src 付きはフレーム内の content script が、srcdoc は親フレームが直接中身をキャプチャする)。

Iframeの中身をJavaScriptで生成(about:blank + document.write)

「Hello from the Iframe!」と本文が表示される(about:blank の iframe は親フレームから document を直接キャプチャする経路)。

ネスト iframe の中の Web Components(DEMO-6668)

Adobe Acrobat Studio に Adobe Express が iframe 埋め込みされている構造の再現。 iframe の中に Shadow DOM があり、iframe 内で :not(:defined) { display: none } が効いている。 shadow 内に別ドメインの <link> CSS / 外部SVGを参照する <use> / img / blob img / canvas。

枠内に青枠のパネル(見出し・説明文・青い丸のアイコン・スイカ画像・緑の blob 画像・青い shadow canvas)が LIVE と同じ並びで表示される。枠内が空(:not(:defined) で全消え)、アイコン抜け(shadow 内 use の参照切れ)、スタイル崩れはデグレ。

iframe内のフォーム状態・canvas・メディア(cross-realm)

iframe 内の document は親ページと別 realm のため instanceof HTMLInputElement 等が常に false になり、 JSON_V1 で入力状態・canvas 等が欠落する不具合があった(localName 判定へ置換して修正)。 cross-realm 経路は about:blank / srcdoc の iframe でしか通らないため、about:blank に親JSでDOMを書き込んでいる。

iframe の背景が薄緑(link CSS 適用)/ text・textarea が「JSで設定した値」/ password の値が password に置換 / checkbox・radio がチェック済み / select が「みかん」/ canvas のグラデーションが残る / img は srcset が削除されて幾何学図形(src)になる / inline style url() の図形が出る / embed は src が空になる / object は data が空になり fallback テキストが表示される。

srcset の赤画像が表示されるのが正常(キャプチャ閲覧時に幾何学図形へ変わる)。

画像・SVG

svgタグ(基本図形)

青い四角と緑の円が表示される。

svg <use> の参照先

hrefで同一ドキュメント内のsvgをパス込みで指定(緑の三角)
hrefで同一ドキュメント内のsvgをハッシュのみで指定(金の星)
hrefで外部svgを読み込み
xlink:hrefで外部svgを読み込み

4 つとも LIVE と同じ図形(緑の三角 / 金の星 / 赤枠の青い円 / 緑枠の黒い四角)が表示される。参照先の symbol は body 末尾の非表示 svg に集約され、use の href は #id 参照に書き換わる(パス込みの同一文書参照も同一文書と判定される)。

SVG camelCase 要素(foreignObject / clipPath / linearGradient / textPath / fe*系)

SVG 名前空間の camelCase タグがキャプチャで小文字化されると、閲覧側で未知のSVG要素として扱われ機能しなくなる。Recharts 等が生成する構造の簡略版。

foreignObject 内の HTML
カスタム凡例 (HTML)
linearGradient + clipPath
textPath
弧に沿った textPath のテキスト
filter(feDropShadow / feGaussianBlur)
symbol + use(同一SVG内参照)
SVGAElement(SVG内の <a>)
SVGAElement Link

すべて元の見た目のまま表示される。foreignObject: 青い角丸ラベル / linearGradient+clipPath: 丸窓に切り抜かれたグラデーション(小文字化されると黒塗り・切り抜き無効)/ textPath: 弧に沿ったテキスト(小文字化されると消える)/ filter: 矩形に影・円にぼかし / symbol+use: 星が3つ / SVGAElement: 「SVGAElement Link」のテキスト。

imgタグ / input type="image"

img URL
URL指定の画像
img Base64
説明文
input type="image" URL
input type="image" Base64

4 つとも猫の画像が表示される(URL の画像は別途アップロードされて差し替えられ、Base64 はインラインのまま残る)。

クッキーが必要なimgタグ

クッキーが必要なimgタグ
クッキーの設定

手順: ボタンで10秒間有効なクッキーを設定 → 10秒以内にキャプチャ。

クッキーが有効なうちにキャプチャすると、閲覧時に画像が表示される。画像は拡張の background が fetch して取得するため、Cookie が付くかは Chrome の挙動次第(壊れて表示される場合はまずここを疑う)。

ページを開いた直後はクッキーが無いため画像が壊れて表示されるのが正常。

background-image(styleタグ / linkタグ / style属性 × URL / Base64)

styleタグ URL
styleタグ Base64
linkタグ URL
linkタグ Base64
style属性 URL
style属性 Base64

6 つすべてに猫の画像(200×200 の範囲)が表示される。

CSS

styleタグ / styleタグ @import / linkタグ

styleタグ
styleタグ
styleタグ @import
styleタグ @import
linkタグ

3 つとも背景が黄緑(yellowgreen)。

@importでCSSをネストして読込

a (red)

a-1 (orange)

a-1-1 (yellow)

a-1-1-1 (lightcoral)

a-1-1-2 (lightgreen)

a-2 (pink) 背景スイカ

b (blue)

b-1 (violet)

c (green)

各行が括弧内の文字色になり、a-2 の背景にスイカ画像が出る(最大4階層の @import と相対パスの url() が解決できている)。

CSS上書き(style → link → style の順で同じセレクタ)

このテキストが青になればよい

テキストが青(赤 → 黒 → 青 の宣言順が維持され、最後の style が勝つ)。

qiankun風スコープ付きCSS(#root / #micro-component-inner プレフィックス除去)

qiankun のページでは CSS に #root .xxx のようなスコープ付きセレクタが現れる。JSON_V1 では #root 配下の階層が保持されないため、 キャプチャ時にプレフィックスを除去する(stripQiankunScopePrefixes)。ここは「除去後の構造」を模写しており、各要素は #root の外(#app 配下)に置き、CSS は #root スコープのまま。

Case 1: #root スコープ / Case 2: #micro-component-inner スコープ
幾何学図形
マイクロアプリのカード
#root を除去した後に .qk-card 単体で発火することを期待
  • 項目A
  • 項目B
  • 項目C
Case 3: #root-inner(除去されない境界ケース + 番兵)
#root-inner .keep-prefix で装飾。#root の直後が空白の時だけ除去するため、ここは除去されず常に紫。

番兵(#root-inner の外): 正常なら無背景の点線枠のまま。 紫背景になったら #root-inner まで誤って除去された=異常。

【JSON_V1】Case 1 は「✓ #root 除去後に…」の青いカード、Case 2 は「✓」付きの緑のリストに変わる。Case 3 の紫ボックスは維持、番兵は無背景の点線枠のまま。 HTML モードではプレフィックスは除去されない(赤いままで正常)。

Case 1 / 2 は赤い「⚠ スコープ除去が効いていない(崩れ)」表示が出るのが正常。

CSSレイアウト(Flexbox / Grid / マルチカラム)

Flexbox

flex-wrap(折り返し)
1
2
3
4
5
6
gap(row-gap: 20px, column-gap: 40px)
1
2
3
4
5
order(DOM順 1,2,3,4 → 表示順 3,1,4,2)
1
2
3
4
flex-direction: column
1(上)
2(中)
3(下)
space-between + align-items: center
1
2
3
space-around + align-items: flex-end
1
2
3
center + align-items: stretch
1
2
3
flex-grow(1 : 2 : 1)/ flex-shrink(幅280px・basis 140px・shrink 1 : 3 : 1)
grow:1
grow:2
grow:1
s:1
s:3
s:1

並び順・折り返し・余白・揃え位置が LIVE と同じ(order は 3,1,4,2 の順に並ぶ / grow は中央が2倍幅 / shrink は中央が一番狭い)。

Grid

grid-template-areas(名前付きエリア)
header
sidebar
main
footer
グリッドスパン(行・列をまたぐ)
1 (2列)
2
3 (2行)
4
5 (2列)
6
7
8
auto-fill + minmax(90px, 1fr)
1
2
3
4
5
6
明示的な columns(60px 2fr 1fr 80px)/ rows + gap(row 20px, column 40px)
60px
2fr
1fr
80px
60px
2fr
1fr
80px

エリア配置・スパン・列幅比が LIVE と同じ。

マルチカラム

column-count: 3 + column-gap: 30px + column-rule

column-rule により段と段の間に 2px の灰色の罫線が表示されます。

罫線は段間の中央に配置されます。テキストが罫線と重ならないことも確認してください。

ブラウザが自動的にコンテンツを各段に分配します。

column-span: all(段をまたぐ見出し)

この段落は通常の3段組みの中にあります。

column-span: all で全段をまたぐ見出し

span後の段落です。見出しの下で再び3段組みが続きます。

2つ目の段落です。

3つ目の段落です。

3段組み・罫線・全段をまたぐ見出しが LIVE と同じ。

position / overflow / スクロール

position: fixed 要素(右下に固定)

position: sticky(スクロールコンテナ内のヘッダー)

stickyヘッダー(スクロールで固定)

コンテンツ 1

コンテンツ 2

コンテンツ 3

コンテンツ 4

コンテンツ 5

コンテンツ 6

コンテンツ 7

コンテンツ 8

コンテンツ 9

コンテンツ 10

コンテンツ 11

コンテンツ 12

コンテナ内をスクロールしても青いヘッダーが上端に貼り付いたまま。

z-index 重なり / position: fixed

z-index: 1
z-index: 2
z-index: 3

赤 → 緑 → 青 の順に手前へ重なる。画面右下の赤い「position: fixed 要素」はページをスクロールしてもビューポート右下に留まる。

overflow / scroll-snap

1. overflow: hidden(ブロック5・6は見えない)
ブロック 1
ブロック 2
ブロック 3
ブロック 4
ブロック 5(見えない)
ブロック 6(見えない)
2. overflow: scroll(常時スクロールバー)
ブロック 1
ブロック 2
ブロック 3
ブロック 4
ブロック 5
ブロック 6
3a. overflow: auto(はみ出しあり)
ブロック 1
ブロック 2
ブロック 3
ブロック 4
ブロック 5
ブロック 6
3b. overflow: auto(はみ出しなし → バー無し)
ブロック 1(収まる)
4a. overflow-x: scroll / overflow-y: hidden
横 1
横 2
横 3
横 4
横 5
4b. overflow-x: hidden / overflow-y: auto
縦 1
縦 2
縦 3
縦 4
縦 5
縦 6
4c. overflow-x: auto / overflow-y: scroll(両方向)
両方向 1
両方向 2
両方向 3
両方向 4
両方向 5
両方向 6
5a. 横スナップ(x mandatory / start)
スライド 1
スライド 2
スライド 3
スライド 4
5b. 横スナップ(center 揃え)
中央 1
中央 2
中央 3
中央 4
5c. 縦スナップ(y mandatory)
ページ 1
ページ 2
ページ 3
ページ 4
5d. proximity スナップ
近接 1
近接 2
近接 3
近接 4

はみ出し部分が枠でクリップされ、スクロールバーの有無(scroll は常時・auto は必要時のみ・hidden は無し)とスクロール可能な方向が LIVE と同じ。スナップも効く。

上下スクロールするテーブル(VRT回帰防止・sticky/固定列)

スクロールするテーブル(グリッド)を「途中までスクロールした状態」でキャプチャしたとき、 配信ページが同じ見た目を復元できるかを検証する。各コンテナは初期スクロール位置を中央にしてあるため、 上下どちらの復元崩れも検出できる。背景: DEMO-5568(LWCグリッドのヘッダー/データ行の横ズレ・スクロール不具合)の再発防止 / DEMO-5946。

A. 縦スクロールテーブル(sticky ヘッダー)

全 40 行・可視 10 行。初期位置は中央(行 15 前後が先頭)。現在の scrollTop: -

# 名称 ステータス 数量 更新日
B. 縦横スクロールグリッド(sticky ヘッダー + 固定 1 列・横長)

DEMO-5568 の LWC グリッドを模した横長構成(全 16 列)。初期位置は縦横とも中央。 scrollTop: - / scrollLeft: -

# 名称 担当 部門 ステータス 1月2月3月4月5月6月 7月8月9月10月11月

各テーブルが「行 15」前後を先頭にした位置で表示される(B は横方向も中央)。紺色のヘッダー行が上端に貼り付き、ヘッダー各列とデータ各列が縦にきっちり揃う(横ズレなし)。上へスクロールすれば行 1〜、下へスクロールすれば行 40 まで見える。

埋め込み系要素(embed / object / iframe)

PDF 等の埋め込み(行 = 参照先 / 列 = 要素)

embed(src)
object(data)
iframe(src)
PDF 絶対パス(GCS)

3 つとも PDF(高齢社会白書)が表示される。キャプチャ時に embed の src / object の data は空になり、PDF 本体は別途収集(getCapturedPdf)される。

PDF 相対パス

絶対パスと同じ。相対パスはキャプチャ中ページの URL を基準に絶対 URL 化して収集される。

PDF Blob URLロード1秒後に js/blobPdfs.js が blob: URL を設定

3 つとも PDF が表示される。blob: URL は URL.createObjectURL をフックして保持した実データから送信される(iframe の blob: src は空になる)。ロードから 1 秒以上待ってからキャプチャする。

Data URL(base64 PDF)

3 つとも PDF が表示される(data: URL を fetch して Content-Type が application/pdf のため PDF として収集される)。

Data URL(base64 JPEG 画像)type 属性は application/pdf のまま

PDF ではないため PDF としては捨てられる。object は data:image として画像収集される。embed は src が空になる(下の data: URL 許可リストが効けば保持)。iframe は src の data: URL がそのまま残る。

Data URL(エンコードなし HTML)

embed / object は src・data が空になり、赤字の Hello World は表示されない。iframe は src の data: URL がそのまま残る(中の DOM はキャプチャされない)。

pdf.js viewer(?file= 絶対URL)ローカルでは表示されないことがある(viewer.mjs の HOSTED_VIEWER_ORIGINS)

embed / object は ?file= 以降の URL を PDF として収集し、PDF が表示される。iframe は PDF の収集に加えて viewer 自体の DOM もキャプチャされる。※ ローカルでは viewer が他オリジンの file を拒否するため、LIVE で空表示でも正常。

pdf.js viewer(?file= 相対パス)

絶対 URL と同じ。?file=/pdf/... はキャプチャ中ページの URL(viewer.html ではない)を基準に絶対 URL 化される。

embed / object の data: URL(自己完結型の保持 / それ以外のクリア)

embed の src / object の data はキャプチャ時にクリアして外部リソースの読み込みを防ぐが、自己完結型の data: URL(画像・動画・音声などの許可リストMIME)は クリアするとコンテンツ自体が失われるため保持する。data:text/html や data:image/svg+xml は内部に script や外部参照を含められるため data: でもクリア(fail-closed)。許可リストは MIME の完全一致判定。

2026-09 時点の拡張 master(ac57b010)には、この許可リストの実装が見当たらない(embed の src / object の data は MIME に関係なく空にしている)。「保持」ケースが空になる場合は、デグレの前に実装状況を確認すること。

外部URLの object(text/html)→ クリア

object の fallback テキスト

data がクリアされ外部を読まない(fallback テキストが出る)。

data:image/png の embed → 保持

src が残り画像(1×1 を引き伸ばし)が表示される。

data:image/png の object → 保持

data が残り画像が表示される。

data:image/gif の embed → 保持

src が残る(1×1 透明GIF のため見た目は空)。

data:audio/wav の embed → 保持

src が残る(無音の最小WAV)。

data:image/svg+xml の embed → クリア

src がクリアされ、黄色の SVG は表示されない。

data:text/html の object → クリア

data がクリアされ、赤い見出しは表示されない。

不正な data: URL(data:foo)→ クリア

「;」「,」区切りが無い不正形式のため src がクリアされる。

data:image/png+xml の embed → クリア

image/png に前方一致するが完全一致しないためクリアされる。

data:image/pngfoo の embed → クリア

前方一致で実装していたら誤って保持してしまう境界ケース。クリアされる。

ShadowDOM / Custom Element

ネストしたShadowDOM(4層)

「1層目」〜「4層目」の 4 行がすべて表示される。

ShadowDOM × CSS

各行が括弧内の色(style タグ=赤 / link=緑 / adoptedStyleSheets=青 / fetch して adopted=黄 / insertRule=ピンク)。shadow 内のスタイルが外(このカードの説明文など)に漏れない。insertRule で追加したルールも cssRules 経由で保存されるので、ピンクになる。

Declarative Shadow DOM × ::part() / CSS Variables

::part() の行がダークオレンジ、CSS Variables の行がグレー。

HTML Custom Element(ハイフン付きタグ名・Shadow DOMなし)

緑の角丸バッジ「custom element のバッジ」が表示される(タグ名 test-badge と connectedCallback で生成した中身がキャプチャされる)。

Canvas

Canvas 描画(スマートフォンUI)

スマートフォン UI の描画が LIVE と同じく表示される(canvas は toDataURL した画像が data-url 属性として保持される)。

Canvas 描画順序(クロスオリジン画像とローカル画像の交互描画)

picsum.photos の画像(crossOrigin 未設定で canvas を taint させる)とローカル生成画像を交互に drawImage し、 拡張の drawImage オーバーライドで描画順序が崩れないかを確認する。後から描いたレイヤーが上に来るのが正しい。

Test 1: 交互描画(3層)

赤 → 写真 → 半透明青。期待: 写真の上に半透明の青が重なる

Test 2: 5層サンドイッチ

赤 → 写真① → 緑 → 写真② → 半透明黄。期待: 黄が最前面、その下に写真②→緑→写真①→赤

Test 3: 同一画像を位置ずらしで3回

期待: 3枚が右下にずれて重なる(後の方が上)

Test 4: transform + クロスオリジン

回転した赤 → 写真 → スケールした半透明青。期待: 回転赤の上に写真、その上にスケール青

4 つとも LIVE と同じ重なり順になる。写真を描いた canvas は taint されるため、拡張設定の「canvas taint 対策(drawImage オーバーライド)」を ON にし、ページをリロードしてからキャプチャする。OFF のままだと toDataURL が SecurityError になり 4 つとも空になる(ON なのに空や順序崩れになればデグレ)。

フォーム・イベント

基本フォーム(text / textarea / select / checkbox / password / submit)

趣味を選んでください:


select は「オレンジ」、趣味は読書・旅行がチェック済み、textarea は「テキストエリア」。パスワードは入力値に関係なく値が password に置換される。form は action=javascript:void(0) / onsubmit="return false;" にされ、送信ボタンを押しても遷移しない。名前欄に入力してからキャプチャすると、その値が残る。

全ての type の input 要素

← 画面には表示されないが input は存在する

各 input の値・チェック・選択が LIVE と同じ(color / range / date 系も value 属性に書き戻される)。password は値が password に置換される。file は選択状態を再現しない。hidden は表示されない。画像ボタンは猫の画像。

onClick が設定されている要素

onClickが設定されているdiv要素

onclick 属性が削除され、クリックしても alert が出ない(削除対象は onclick だけで、onmousedown などは残る)。

クリックすると alert が出る(自動操作ツールで開いている場合は押さないこと)。

リンク・noscript・不正なDOM構造

リンク / noscript

リンク
Google
noscript

リンク文字列「Google」が表示される(HTML モードでは href が javascript:void(0) に書き換わり遷移しない)。noscript の中の赤字は表示されない。

不正なDOM構造(JS で動的に生成)

pタグのネスト

p

buttonタグのネスト
liタグのネスト
  • li
  • 1
  • 2
tableタグ配下以外の場所でのtbody
親div
thタグのネスト
Header 1 Header 2 Header 3 Header 4 Header 5
Data 1 Data 2 Data 3 Data 4 Data 5

p > div / p > p / p > span > div、button 内の button1・button2、li > li、th > th1・th2、親div 内の赤い「div > tbody (red)」が LIVE と同じ並び・入れ子で表示される(JSON_V1 はそのまま保存し、HTML モードは不正な子要素を span などに置き換えて崩れを防ぐ)。

tr内にtd以外の要素があるtable

div1が表示される td1が表示される td2が表示される visibility: hiddenのdiv要素が存在している td3が表示される

tr の子に input[type=hidden] / display:none(inline・CSS)の input・div / 通常の div / visibility:hidden の div を JS で混ぜている。

LIVE と同じく、各列の見出しどおり div1 / td1 / td2 /(visibility:hidden で空)/ td3 が並ぶ。display:none の要素は表示されず、列もずれない(HTML モードでは tr 直下の div が td で包まれるが、display:none の要素は包まれない)。