◆ document.documentElement の outerHTML
  ◆ JavaScript で操作された現時点の html タグ以下が取れる
◆ document.doctype で doctype はとれるけど xhtml の xml 宣言は取れない
◆ JavaScript の操作前の状態がほしいなら fetch("") で自分のページをリクエスト

JavaScript が動いてるページ自身の HTML がほしいです

ぱっと思いつくのは
document.body.innerHTML

html タグも含めて全体なら
document.doctype.valueOf() + "\n" + document.documentElement.outerHTML
です

document.documentElement が html タグのことです
doctype は document.doctype でとれるのですが textContent や name で全体の doctype テキストがとれずに
dir(document.doctype)
でプロパティ一覧を見てもそれらしいプロパティがないので valueOf でとりました

toString は "[object DocumentType]" になるのでだめです
あと doctype が無いページは null になるので null かどうかで場合分けする必要があります


それでも この方法では完全に全体は取れません
doctype まではとれるのですが 少し昔に使われていた XHTML のページでの XML 宣言が取得できません
XHTML の書き始めはこういうのです
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

この 2 行目は上の方法で取得できますが 1 行目が取得できません
document.xmlVersion
というそれっぽいプロパティがありますが XHTML ページでも null でした


そして一番の問題は レスポンスとして受け取った HTML 自体でないこと です

innerHTML や outerHTML で取得するのは現時点の DOM ツリーのデータです
JavaScript で要素を追加したり減らしたりあれこれ変更していたらそれが適用済みです
また JavaScript は使っていなくても HTML 構文的におかしいところをブラウザが自動で修正済みになっています

そういったものが適用済みでも良い場合は別にいいのですが URL にアクセスしたら返ってくるテキスト自体がほしいときにはこの方法は使えません


調べてみても初期のソースを保持してはいないようなので 自分自身の URL を再度リクエストするのが良さそうです
const source = await fetch("").then(e => e.text())

キャッシュされてるはずですし遅くはないと思います

テキストじゃなくて DOM として扱うなら DOMParser を使います
body の innerHTML がほしいなら
const source = await fetch("").then(e => e.text())
const body_inner = new DOMParser().parseFromString(source, "text/html").body.innerHTML

こういう感じです
await ありなので async 付き関数の中で実行してください

DOM パースしているので HTML 構造としておかしいところの修正は行われてしまいます
それが困るなら正規表現でするしかないと思います