[{"data":1,"prerenderedAt":1778},["ShallowReactive",2],{"navigation_docs":3,"-guides-testing":216,"-guides-testing-surround":1773},[4,42,68,115,136,157],{"title":5,"path":6,"stem":7,"children":8,"icon":11},"Getting Started","\u002Fgetting-started","1.getting-started\u002F0.index",[9,12,17,22,27,32,37],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-sparkles",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F2.configuration","i-lucide-settings",{"title":23,"path":24,"stem":25,"icon":26},"Client Setup","\u002Fgetting-started\u002Fclient-setup","1.getting-started\u002F3.client-setup","i-lucide-monitor",{"title":28,"path":29,"stem":30,"icon":31},"Type Augmentation","\u002Fgetting-started\u002Ftype-augmentation","1.getting-started\u002F4.type-augmentation","i-lucide-type",{"title":33,"path":34,"stem":35,"icon":36},"Schema Generation (NuxtHub)","\u002Fgetting-started\u002Fschema-generation","1.getting-started\u002F5.schema-generation","i-lucide-database",{"title":38,"path":39,"stem":40,"icon":41},"How It Works","\u002Fgetting-started\u002Fhow-it-works","1.getting-started\u002F6.how-it-works","i-lucide-workflow",{"title":43,"path":44,"stem":45,"children":46,"page":67},"Core Concepts","\u002Fcore-concepts","2.core-concepts",[47,51,55,59,63],{"title":48,"path":49,"stem":50},"serverAuth()","\u002Fcore-concepts\u002Fserver-auth","2.core-concepts\u002F1.server-auth",{"title":52,"path":53,"stem":54},"Sessions","\u002Fcore-concepts\u002Fsessions","2.core-concepts\u002F2.sessions",{"title":56,"path":57,"stem":58},"Route Protection","\u002Fcore-concepts\u002Froute-protection","2.core-concepts\u002F3.route-protection",{"title":60,"path":61,"stem":62},"Auto‑Imports and Aliases","\u002Fcore-concepts\u002Fauto-imports-aliases","2.core-concepts\u002F4.auto-imports-aliases",{"title":64,"path":65,"stem":66},"Security & Caveats","\u002Fcore-concepts\u002Fsecurity-caveats","2.core-concepts\u002F5.security-caveats",false,{"title":69,"path":70,"stem":71,"children":72,"page":67},"Guides","\u002Fguides","3.guides",[73,77,82,86,90,94,99,103,107,111],{"title":74,"path":75,"stem":76},"Role‑Based Access","\u002Fguides\u002Frole-based-access","3.guides\u002F1.role-based-access",{"title":78,"path":79,"stem":80,"icon":81},"Setup diagnostics","\u002Fguides\u002Fdiagnostics","3.guides\u002F10.diagnostics","i-lucide-circle-alert",{"title":83,"path":84,"stem":85},"OAuth Providers","\u002Fguides\u002Foauth-providers","3.guides\u002F2.oauth-providers",{"title":87,"path":88,"stem":89},"Custom Database","\u002Fguides\u002Fcustom-database","3.guides\u002F3.custom-database",{"title":91,"path":92,"stem":93},"Database-less Mode","\u002Fguides\u002Fdatabase-less-mode","3.guides\u002F4.database-less-mode",{"title":95,"path":96,"stem":97,"icon":98},"External Auth Backend","\u002Fguides\u002Fexternal-auth-backend","3.guides\u002F5.external-auth-backend","i-lucide-server",{"title":100,"path":101,"stem":102},"Migrating from nuxt-auth-utils","\u002Fguides\u002Fmigrate-from-nuxt-auth-utils","3.guides\u002F6.migrate-from-nuxt-auth-utils",{"title":104,"path":105,"stem":106},"Two-Factor Authentication (TOTP + Backup Codes)","\u002Fguides\u002Ftwo-factor-auth","3.guides\u002F7.two-factor-auth",{"title":108,"path":109,"stem":110},"Testing","\u002Fguides\u002Ftesting","3.guides\u002F8.testing",{"title":112,"path":113,"stem":114},"Production Deployment","\u002Fguides\u002Fproduction-deployment","3.guides\u002F9.production-deployment",{"title":116,"path":117,"stem":118,"children":119,"page":67},"Integrations","\u002Fintegrations","4.integrations",[120,124,128,132],{"title":121,"path":122,"stem":123},"NuxtHub","\u002Fintegrations\u002Fnuxthub","4.integrations\u002F1.nuxthub",{"title":125,"path":126,"stem":127},"DevTools","\u002Fintegrations\u002Fdevtools","4.integrations\u002F2.devtools",{"title":129,"path":130,"stem":131},"Convex","\u002Fintegrations\u002Fconvex","4.integrations\u002F3.convex",{"title":133,"path":134,"stem":135},"i18n","\u002Fintegrations\u002Fi18n","4.integrations\u002F4.i18n",{"title":137,"path":138,"stem":139,"children":140,"page":67},"API Reference","\u002Fapi","5.api",[141,145,149,153],{"title":142,"path":143,"stem":144},"Composables","\u002Fapi\u002Fcomposables","5.api\u002F1.composables",{"title":146,"path":147,"stem":148},"Server Utilities","\u002Fapi\u002Fserver-utils","5.api\u002F2.server-utils",{"title":150,"path":151,"stem":152},"Components","\u002Fapi\u002Fcomponents","5.api\u002F3.components",{"title":154,"path":155,"stem":156},"Types","\u002Fapi\u002Ftypes","5.api\u002F4.types",{"title":158,"path":159,"stem":160,"children":161,"icon":81},"Errors","\u002Ferrors","6.errors\u002F0.index",[162,164,168,172,176,180,184,188,192,196,200,204,208,212],{"title":163,"path":159,"stem":160},"Overview",{"title":165,"path":166,"stem":167},"Better Auth CLI is not installed","\u002Ferrors\u002Fnuxt-auth-cli-missing","6.errors\u002Fnuxt-auth-cli-missing",{"title":169,"path":170,"stem":171},"Better Auth CLI version does not match better-auth","\u002Ferrors\u002Fnuxt-auth-cli-version-mismatch","6.errors\u002Fnuxt-auth-cli-version-mismatch",{"title":173,"path":174,"stem":175},"Auth configuration failed to load","\u002Ferrors\u002Fnuxt-auth-config-load-failed","6.errors\u002Fnuxt-auth-config-load-failed",{"title":177,"path":178,"stem":179},"Schema generator returned no code","\u002Ferrors\u002Fnuxt-auth-empty-schema","6.errors\u002Fnuxt-auth-empty-schema",{"title":181,"path":182,"stem":183},"Invalid server auth config export","\u002Ferrors\u002Fnuxt-auth-invalid-config-export","6.errors\u002Fnuxt-auth-invalid-config-export",{"title":185,"path":186,"stem":187},"Auth plugin path must be absolute","\u002Ferrors\u002Fnuxt-auth-invalid-plugin-source","6.errors\u002Fnuxt-auth-invalid-plugin-source",{"title":189,"path":190,"stem":191},"Missing auth configuration","\u002Ferrors\u002Fnuxt-auth-missing-config","6.errors\u002Fnuxt-auth-missing-config",{"title":193,"path":194,"stem":195},"NuxtHub database alias is missing","\u002Ferrors\u002Fnuxt-auth-missing-hub-db","6.errors\u002Fnuxt-auth-missing-hub-db",{"title":197,"path":198,"stem":199},"No database provider is enabled","\u002Ferrors\u002Fnuxt-auth-no-database-provider","6.errors\u002Fnuxt-auth-no-database-provider",{"title":201,"path":202,"stem":203},"Auth schema generation failed","\u002Ferrors\u002Fnuxt-auth-schema-generation-failed","6.errors\u002Fnuxt-auth-schema-generation-failed",{"title":205,"path":206,"stem":207},"Custom session storage is missing","\u002Ferrors\u002Fnuxt-auth-schema-storage-required","6.errors\u002Fnuxt-auth-schema-storage-required",{"title":209,"path":210,"stem":211},"Secondary storage in client-only mode","\u002Ferrors\u002Fnuxt-auth-storage-client-only","6.errors\u002Fnuxt-auth-storage-client-only",{"title":213,"path":214,"stem":215},"Unsupported database dialect","\u002Ferrors\u002Fnuxt-auth-unsupported-dialect","6.errors\u002Fnuxt-auth-unsupported-dialect",{"id":217,"title":108,"body":218,"description":1767,"extension":1768,"links":1769,"meta":1770,"navigation":391,"path":109,"seo":1771,"stem":110,"__hash__":1772},"docs\u002F3.guides\u002F8.testing.md",{"type":219,"value":220,"toc":1763},"minimark",[221,238,243,273,282,938,953,983,987,1029,1032,1117,1120,1685,1699,1709,1744,1755,1759],[222,223,224,225,232,233,237],"p",{},"The module provides separate helpers for Nuxt's runtime and end-to-end test environments. Follow ",[226,227,231],"a",{"href":228,"rel":229},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Ftesting",[230],"nofollow","Nuxt's testing setup"," to configure Vitest and install ",[234,235,236],"code",{},"@nuxt\u002Ftest-utils",".",[239,240,242],"h2",{"id":241},"mocking-useusersession","Mocking useUserSession",[222,244,245,246,249,250,253,254,257,258,261,262,261,265,268,269,272],{},"Use ",[234,247,248],{},"createUserSessionMock"," with ",[234,251,252],{},"mockNuxtImport"," to replace ",[234,255,256],{},"useUserSession",". It provides reactive ",[234,259,260],{},"user",", ",[234,263,264],{},"session",[234,266,267],{},"loggedIn",", and ",[234,270,271],{},"ready"," refs, plus the composable's session methods.",[222,274,275,277,278,281],{},[234,276,252],{}," is hoisted, so create the mock inside ",[234,279,280],{},"vi.hoisted",":",[283,284,290],"pre",{"className":285,"code":286,"filename":287,"language":288,"meta":289,"style":289},"language-ts shiki shiki-themes one-light synthwave-84 synthwave-84","import { mockNuxtImport, mountSuspended } from '@nuxt\u002Ftest-utils\u002Fruntime'\nimport { beforeEach, expect, it, vi } from 'vitest'\nimport { nextTick } from 'vue'\nimport AuthStatus from '~\u002Fcomponents\u002FAuthStatus.vue'\n\nconst { auth } = await vi.hoisted(async () => {\n  const { createUserSessionMock } = await import('@nuxtjs\u002Fbetter-auth\u002Ftest-utils\u002Fruntime')\n  return { auth: createUserSessionMock() }\n})\n\nmockNuxtImport('useUserSession', () => () => auth)\nbeforeEach(() => auth.reset())\n\nit('reacts to session changes', async () => {\n  const component = await mountSuspended(AuthStatus)\n  expect(component.text()).toContain('Signed out')\n\n  const now = new Date()\n  auth.setSession({\n    user: {\n      id: 'user-1', name: 'Viewer', email: 'viewer@example.test',\n      emailVerified: true, createdAt: now, updatedAt: now,\n    },\n    session: {\n      id: 'session-1', userId: 'user-1',\n      createdAt: now, updatedAt: now,\n      expiresAt: new Date(Date.now() + 3600_000),\n    },\n  })\n  await nextTick()\n  expect(component.text()).toContain('Signed in')\n\n  await auth.signOut()\n  await nextTick()\n  expect(component.text()).toContain('Signed out')\n  component.unmount()\n})\n","tests\u002Fnuxt\u002Fauth-status.nuxt.spec.ts","ts","",[234,291,292,323,355,372,386,393,439,467,486,492,497,521,541,546,566,589,618,623,642,656,666,700,732,738,748,769,789,823,828,834,845,869,874,888,897,920,933],{"__ignoreMap":289},[293,294,297,301,305,308,310,313,316,319],"span",{"class":295,"line":296},"line",1,[293,298,300],{"class":299},"sqe1H","import",[293,302,304],{"class":303},"s17Py"," { ",[293,306,252],{"class":307},"sYvLG",[293,309,261],{"class":303},[293,311,312],{"class":307},"mountSuspended",[293,314,315],{"class":303}," } ",[293,317,318],{"class":299},"from",[293,320,322],{"class":321},"sPAZv"," '@nuxt\u002Ftest-utils\u002Fruntime'\n",[293,324,326,328,330,333,335,338,340,343,345,348,350,352],{"class":295,"line":325},2,[293,327,300],{"class":299},[293,329,304],{"class":303},[293,331,332],{"class":307},"beforeEach",[293,334,261],{"class":303},[293,336,337],{"class":307},"expect",[293,339,261],{"class":303},[293,341,342],{"class":307},"it",[293,344,261],{"class":303},[293,346,347],{"class":307},"vi",[293,349,315],{"class":303},[293,351,318],{"class":299},[293,353,354],{"class":321}," 'vitest'\n",[293,356,358,360,362,365,367,369],{"class":295,"line":357},3,[293,359,300],{"class":299},[293,361,304],{"class":303},[293,363,364],{"class":307},"nextTick",[293,366,315],{"class":303},[293,368,318],{"class":299},[293,370,371],{"class":321}," 'vue'\n",[293,373,375,377,380,383],{"class":295,"line":374},4,[293,376,300],{"class":299},[293,378,379],{"class":307}," AuthStatus",[293,381,382],{"class":299}," from",[293,384,385],{"class":321}," '~\u002Fcomponents\u002FAuthStatus.vue'\n",[293,387,389],{"class":295,"line":388},5,[293,390,392],{"emptyLinePlaceholder":391},true,"\n",[293,394,396,399,401,405,407,411,414,418,420,424,427,430,433,436],{"class":295,"line":395},6,[293,397,398],{"class":299},"const",[293,400,304],{"class":303},[293,402,404],{"class":403},"s6Rhl","auth",[293,406,315],{"class":303},[293,408,410],{"class":409},"sQBpM","=",[293,412,413],{"class":299}," await",[293,415,417],{"class":416},"svFNh"," vi",[293,419,237],{"class":303},[293,421,423],{"class":422},"sfT9l","hoisted",[293,425,426],{"class":303},"(",[293,428,429],{"class":299},"async",[293,431,432],{"class":303}," () ",[293,434,435],{"class":299},"=>",[293,437,438],{"class":303}," {\n",[293,440,442,445,447,449,451,453,455,459,461,464],{"class":295,"line":441},7,[293,443,444],{"class":299},"  const",[293,446,304],{"class":303},[293,448,248],{"class":403},[293,450,315],{"class":303},[293,452,410],{"class":409},[293,454,413],{"class":299},[293,456,458],{"class":457},"sn-Jc"," import",[293,460,426],{"class":303},[293,462,463],{"class":321},"'@nuxtjs\u002Fbetter-auth\u002Ftest-utils\u002Fruntime'",[293,465,466],{"class":303},")\n",[293,468,470,473,475,477,480,483],{"class":295,"line":469},8,[293,471,472],{"class":299},"  return",[293,474,304],{"class":303},[293,476,404],{"class":307},[293,478,281],{"class":479},"sVnqq",[293,481,482],{"class":422}," createUserSessionMock",[293,484,485],{"class":303},"() }\n",[293,487,489],{"class":295,"line":488},9,[293,490,491],{"class":303},"})\n",[293,493,495],{"class":295,"line":494},10,[293,496,392],{"emptyLinePlaceholder":391},[293,498,500,502,504,507,510,512,514,516,519],{"class":295,"line":499},11,[293,501,252],{"class":422},[293,503,426],{"class":303},[293,505,506],{"class":321},"'useUserSession'",[293,508,509],{"class":303},", () ",[293,511,435],{"class":299},[293,513,432],{"class":303},[293,515,435],{"class":299},[293,517,518],{"class":416}," auth",[293,520,466],{"class":303},[293,522,524,526,529,531,533,535,538],{"class":295,"line":523},12,[293,525,332],{"class":422},[293,527,528],{"class":303},"(() ",[293,530,435],{"class":299},[293,532,518],{"class":416},[293,534,237],{"class":303},[293,536,537],{"class":422},"reset",[293,539,540],{"class":303},"())\n",[293,542,544],{"class":295,"line":543},13,[293,545,392],{"emptyLinePlaceholder":391},[293,547,549,551,553,556,558,560,562,564],{"class":295,"line":548},14,[293,550,342],{"class":422},[293,552,426],{"class":303},[293,554,555],{"class":321},"'reacts to session changes'",[293,557,261],{"class":303},[293,559,429],{"class":299},[293,561,432],{"class":303},[293,563,435],{"class":299},[293,565,438],{"class":303},[293,567,569,571,574,577,579,582,584,587],{"class":295,"line":568},15,[293,570,444],{"class":299},[293,572,573],{"class":403}," component",[293,575,576],{"class":409}," =",[293,578,413],{"class":299},[293,580,581],{"class":422}," mountSuspended",[293,583,426],{"class":303},[293,585,586],{"class":416},"AuthStatus",[293,588,466],{"class":303},[293,590,592,595,597,600,602,605,608,611,613,616],{"class":295,"line":591},16,[293,593,594],{"class":422},"  expect",[293,596,426],{"class":303},[293,598,599],{"class":416},"component",[293,601,237],{"class":303},[293,603,604],{"class":422},"text",[293,606,607],{"class":303},"()).",[293,609,610],{"class":422},"toContain",[293,612,426],{"class":303},[293,614,615],{"class":321},"'Signed out'",[293,617,466],{"class":303},[293,619,621],{"class":295,"line":620},17,[293,622,392],{"emptyLinePlaceholder":391},[293,624,626,628,631,633,636,639],{"class":295,"line":625},18,[293,627,444],{"class":299},[293,629,630],{"class":403}," now",[293,632,576],{"class":409},[293,634,635],{"class":299}," new",[293,637,638],{"class":422}," Date",[293,640,641],{"class":303},"()\n",[293,643,645,648,650,653],{"class":295,"line":644},19,[293,646,647],{"class":416},"  auth",[293,649,237],{"class":303},[293,651,652],{"class":422},"setSession",[293,654,655],{"class":303},"({\n",[293,657,659,662,664],{"class":295,"line":658},20,[293,660,661],{"class":307},"    user",[293,663,281],{"class":479},[293,665,438],{"class":303},[293,667,669,672,674,677,679,682,684,687,689,692,694,697],{"class":295,"line":668},21,[293,670,671],{"class":307},"      id",[293,673,281],{"class":479},[293,675,676],{"class":321}," 'user-1'",[293,678,261],{"class":303},[293,680,681],{"class":307},"name",[293,683,281],{"class":479},[293,685,686],{"class":321}," 'Viewer'",[293,688,261],{"class":303},[293,690,691],{"class":307},"email",[293,693,281],{"class":479},[293,695,696],{"class":321}," 'viewer@example.test'",[293,698,699],{"class":303},",\n",[293,701,703,706,708,712,714,717,719,721,723,726,728,730],{"class":295,"line":702},22,[293,704,705],{"class":307},"      emailVerified",[293,707,281],{"class":479},[293,709,711],{"class":710},"s3ZNE"," true",[293,713,261],{"class":303},[293,715,716],{"class":307},"createdAt",[293,718,281],{"class":479},[293,720,630],{"class":416},[293,722,261],{"class":303},[293,724,725],{"class":307},"updatedAt",[293,727,281],{"class":479},[293,729,630],{"class":416},[293,731,699],{"class":303},[293,733,735],{"class":295,"line":734},23,[293,736,737],{"class":303},"    },\n",[293,739,741,744,746],{"class":295,"line":740},24,[293,742,743],{"class":307},"    session",[293,745,281],{"class":479},[293,747,438],{"class":303},[293,749,751,753,755,758,760,763,765,767],{"class":295,"line":750},25,[293,752,671],{"class":307},[293,754,281],{"class":479},[293,756,757],{"class":321}," 'session-1'",[293,759,261],{"class":303},[293,761,762],{"class":307},"userId",[293,764,281],{"class":479},[293,766,676],{"class":321},[293,768,699],{"class":303},[293,770,772,775,777,779,781,783,785,787],{"class":295,"line":771},26,[293,773,774],{"class":307},"      createdAt",[293,776,281],{"class":479},[293,778,630],{"class":416},[293,780,261],{"class":303},[293,782,725],{"class":307},[293,784,281],{"class":479},[293,786,630],{"class":416},[293,788,699],{"class":303},[293,790,792,795,797,799,801,803,806,808,811,814,817,820],{"class":295,"line":791},27,[293,793,794],{"class":307},"      expiresAt",[293,796,281],{"class":479},[293,798,635],{"class":299},[293,800,638],{"class":422},[293,802,426],{"class":303},[293,804,805],{"class":416},"Date",[293,807,237],{"class":303},[293,809,810],{"class":422},"now",[293,812,813],{"class":303},"() ",[293,815,816],{"class":457},"+",[293,818,819],{"class":710}," 3600_000",[293,821,822],{"class":303},"),\n",[293,824,826],{"class":295,"line":825},28,[293,827,737],{"class":303},[293,829,831],{"class":295,"line":830},29,[293,832,833],{"class":303},"  })\n",[293,835,837,840,843],{"class":295,"line":836},30,[293,838,839],{"class":299},"  await",[293,841,842],{"class":422}," nextTick",[293,844,641],{"class":303},[293,846,848,850,852,854,856,858,860,862,864,867],{"class":295,"line":847},31,[293,849,594],{"class":422},[293,851,426],{"class":303},[293,853,599],{"class":416},[293,855,237],{"class":303},[293,857,604],{"class":422},[293,859,607],{"class":303},[293,861,610],{"class":422},[293,863,426],{"class":303},[293,865,866],{"class":321},"'Signed in'",[293,868,466],{"class":303},[293,870,872],{"class":295,"line":871},32,[293,873,392],{"emptyLinePlaceholder":391},[293,875,877,879,881,883,886],{"class":295,"line":876},33,[293,878,839],{"class":299},[293,880,518],{"class":416},[293,882,237],{"class":303},[293,884,885],{"class":422},"signOut",[293,887,641],{"class":303},[293,889,891,893,895],{"class":295,"line":890},34,[293,892,839],{"class":299},[293,894,842],{"class":422},[293,896,641],{"class":303},[293,898,900,902,904,906,908,910,912,914,916,918],{"class":295,"line":899},35,[293,901,594],{"class":422},[293,903,426],{"class":303},[293,905,599],{"class":416},[293,907,237],{"class":303},[293,909,604],{"class":422},[293,911,607],{"class":303},[293,913,610],{"class":422},[293,915,426],{"class":303},[293,917,615],{"class":321},[293,919,466],{"class":303},[293,921,923,926,928,931],{"class":295,"line":922},36,[293,924,925],{"class":416},"  component",[293,927,237],{"class":303},[293,929,930],{"class":422},"unmount",[293,932,641],{"class":303},[293,934,936],{"class":295,"line":935},37,[293,937,491],{"class":303},[222,939,940,941,944,945,948,949,952],{},"Supply any required additional fields from your auth configuration. ",[234,942,943],{},"reset()"," restores a copy of the initial session passed to the factory, or the signed-out state when omitted. ",[234,946,947],{},"setSession(null, { ready: false })"," models a pending session; ",[234,950,951],{},"waitForSession()"," waits until the mock is logged in, or for five seconds, just like the real composable. Use Vitest fake timers to test the timeout.",[222,954,955,958,959,962,963,966,967,970,971,974,975,978,979,982],{},[234,956,957],{},"updateUser()"," merges fields into the mock user. ",[234,960,961],{},"signOut()"," clears the session and calls an optional ",[234,964,965],{},"onSuccess"," callback. ",[234,968,969],{},"fetchSession()"," does nothing by default; replace it with ",[234,972,973],{},"vi.fn()"," when testing refresh behavior. These methods make no network requests. Mock ",[234,976,977],{},"useSignIn"," and ",[234,980,981],{},"useSignUp"," separately when testing login forms.",[239,984,986],{"id":985},"creating-sessions-for-end-to-end-tests","Creating sessions for end-to-end tests",[222,988,245,989,992,993,996,997,1000,1001,261,1004,268,1007,1010,1011,1014,1015,978,1018,1021,1022,1025,1026,237],{},[234,990,991],{},"createAuthTestContext"," with the server started by ",[234,994,995],{},"@nuxt\u002Ftest-utils\u002Fe2e",". It installs Better Auth's ",[234,998,999],{},"testUtils"," plugin and exposes ",[234,1002,1003],{},"createUser",[234,1005,1006],{},"login",[234,1008,1009],{},"clear"," through a private test route. Pass your usual Nuxt ",[234,1012,1013],{},"setup()"," options to the factory. It merges your ",[234,1016,1017],{},"nuxtConfig",[234,1019,1020],{},"env"," with the test module, selects a local port or uses your ",[234,1023,1024],{},"port",", and configures the matching ",[234,1027,1028],{},"siteUrl",[222,1030,1031],{},"Configure a local Better Auth server and an isolated test database in your fixture. For example:",[283,1033,1036],{"className":285,"code":1034,"filename":1035,"language":288,"meta":289,"style":289},"import { memoryAdapter } from 'better-auth\u002Fadapters\u002Fmemory'\n\nexport default defineServerAuth({\n  database: memoryAdapter({ user: [], session: [], account: [], verification: [] }),\n})\n","tests\u002Ffixtures\u002Fauth\u002Fserver\u002Fauth.config.ts",[234,1037,1038,1054,1058,1072,1113],{"__ignoreMap":289},[293,1039,1040,1042,1044,1047,1049,1051],{"class":295,"line":296},[293,1041,300],{"class":299},[293,1043,304],{"class":303},[293,1045,1046],{"class":307},"memoryAdapter",[293,1048,315],{"class":303},[293,1050,318],{"class":299},[293,1052,1053],{"class":321}," 'better-auth\u002Fadapters\u002Fmemory'\n",[293,1055,1056],{"class":295,"line":325},[293,1057,392],{"emptyLinePlaceholder":391},[293,1059,1060,1063,1067,1070],{"class":295,"line":357},[293,1061,1062],{"class":299},"export",[293,1064,1066],{"class":1065},"sKg8T"," default",[293,1068,1069],{"class":422}," defineServerAuth",[293,1071,655],{"class":303},[293,1073,1074,1077,1079,1082,1085,1087,1089,1092,1094,1096,1098,1101,1103,1105,1108,1110],{"class":295,"line":374},[293,1075,1076],{"class":307},"  database",[293,1078,281],{"class":479},[293,1080,1081],{"class":422}," memoryAdapter",[293,1083,1084],{"class":303},"({ ",[293,1086,260],{"class":307},[293,1088,281],{"class":479},[293,1090,1091],{"class":303}," [], ",[293,1093,264],{"class":307},[293,1095,281],{"class":479},[293,1097,1091],{"class":303},[293,1099,1100],{"class":307},"account",[293,1102,281],{"class":479},[293,1104,1091],{"class":303},[293,1106,1107],{"class":307},"verification",[293,1109,281],{"class":479},[293,1111,1112],{"class":303}," [] }),\n",[293,1114,1115],{"class":295,"line":388},[293,1116,491],{"class":303},[222,1118,1119],{},"Use the login result's headers for HTTP tests and its cookies for Playwright:",[283,1121,1124],{"className":285,"code":1122,"filename":1123,"language":288,"meta":289,"style":289},"import { fileURLToPath } from 'node:url'\nimport { $fetch, getBrowser, setup, url } from '@nuxt\u002Ftest-utils\u002Fe2e'\nimport { createAuthTestContext } from '@nuxtjs\u002Fbetter-auth\u002Ftest-utils\u002Fe2e'\nimport { afterEach, describe, expect, it } from 'vitest'\n\nconst auth = await createAuthTestContext({\n  rootDir: fileURLToPath(new URL('..\u002Ffixtures\u002Fauth', import.meta.url)),\n  browser: true,\n})\n\ndescribe('Authenticated access', async () => {\n  await setup(auth.setupOptions)\n  afterEach(() => auth.clear())\n\n  it('uses the same session for API requests and pages', async () => {\n    const user = await auth.createUser({ name: 'Test viewer' })\n    const { headers, cookies } = await auth.login({ userId: user.id })\n    const me = await $fetch('\u002Fapi\u002Fme', { headers })\n    expect(me.user.id).toBe(user.id)\n\n    const browser = await getBrowser()\n    const context = await browser.newContext()\n    try {\n      await context.addCookies(cookies)\n      const page = await context.newPage()\n      await page.goto(url('\u002Fprotected'))\n      expect(await page.getByText('Test viewer').textContent()).toBe('Test viewer')\n    }\n    finally {\n      await context.close()\n    }\n  })\n})\n","tests\u002Fe2e\u002Fauth.test.ts",[234,1125,1126,1142,1173,1188,1216,1220,1235,1274,1285,1289,1293,1312,1330,1347,1351,1371,1401,1442,1468,1502,1506,1522,1542,1549,1567,1588,1611,1648,1653,1660,1673,1677,1681],{"__ignoreMap":289},[293,1127,1128,1130,1132,1135,1137,1139],{"class":295,"line":296},[293,1129,300],{"class":299},[293,1131,304],{"class":303},[293,1133,1134],{"class":307},"fileURLToPath",[293,1136,315],{"class":303},[293,1138,318],{"class":299},[293,1140,1141],{"class":321}," 'node:url'\n",[293,1143,1144,1146,1148,1151,1153,1156,1158,1161,1163,1166,1168,1170],{"class":295,"line":325},[293,1145,300],{"class":299},[293,1147,304],{"class":303},[293,1149,1150],{"class":307},"$fetch",[293,1152,261],{"class":303},[293,1154,1155],{"class":307},"getBrowser",[293,1157,261],{"class":303},[293,1159,1160],{"class":307},"setup",[293,1162,261],{"class":303},[293,1164,1165],{"class":307},"url",[293,1167,315],{"class":303},[293,1169,318],{"class":299},[293,1171,1172],{"class":321}," '@nuxt\u002Ftest-utils\u002Fe2e'\n",[293,1174,1175,1177,1179,1181,1183,1185],{"class":295,"line":357},[293,1176,300],{"class":299},[293,1178,304],{"class":303},[293,1180,991],{"class":307},[293,1182,315],{"class":303},[293,1184,318],{"class":299},[293,1186,1187],{"class":321}," '@nuxtjs\u002Fbetter-auth\u002Ftest-utils\u002Fe2e'\n",[293,1189,1190,1192,1194,1197,1199,1202,1204,1206,1208,1210,1212,1214],{"class":295,"line":374},[293,1191,300],{"class":299},[293,1193,304],{"class":303},[293,1195,1196],{"class":307},"afterEach",[293,1198,261],{"class":303},[293,1200,1201],{"class":307},"describe",[293,1203,261],{"class":303},[293,1205,337],{"class":307},[293,1207,261],{"class":303},[293,1209,342],{"class":307},[293,1211,315],{"class":303},[293,1213,318],{"class":299},[293,1215,354],{"class":321},[293,1217,1218],{"class":295,"line":388},[293,1219,392],{"emptyLinePlaceholder":391},[293,1221,1222,1224,1226,1228,1230,1233],{"class":295,"line":395},[293,1223,398],{"class":299},[293,1225,518],{"class":403},[293,1227,576],{"class":409},[293,1229,413],{"class":299},[293,1231,1232],{"class":422}," createAuthTestContext",[293,1234,655],{"class":303},[293,1236,1237,1240,1242,1245,1247,1250,1253,1255,1258,1260,1262,1264,1267,1269,1271],{"class":295,"line":441},[293,1238,1239],{"class":307},"  rootDir",[293,1241,281],{"class":479},[293,1243,1244],{"class":422}," fileURLToPath",[293,1246,426],{"class":303},[293,1248,1249],{"class":299},"new",[293,1251,1252],{"class":422}," URL",[293,1254,426],{"class":303},[293,1256,1257],{"class":321},"'..\u002Ffixtures\u002Fauth'",[293,1259,261],{"class":303},[293,1261,300],{"class":299},[293,1263,237],{"class":303},[293,1265,1266],{"class":307},"meta",[293,1268,237],{"class":303},[293,1270,1165],{"class":307},[293,1272,1273],{"class":303},")),\n",[293,1275,1276,1279,1281,1283],{"class":295,"line":469},[293,1277,1278],{"class":307},"  browser",[293,1280,281],{"class":479},[293,1282,711],{"class":710},[293,1284,699],{"class":303},[293,1286,1287],{"class":295,"line":488},[293,1288,491],{"class":303},[293,1290,1291],{"class":295,"line":494},[293,1292,392],{"emptyLinePlaceholder":391},[293,1294,1295,1297,1299,1302,1304,1306,1308,1310],{"class":295,"line":499},[293,1296,1201],{"class":422},[293,1298,426],{"class":303},[293,1300,1301],{"class":321},"'Authenticated access'",[293,1303,261],{"class":303},[293,1305,429],{"class":299},[293,1307,432],{"class":303},[293,1309,435],{"class":299},[293,1311,438],{"class":303},[293,1313,1314,1316,1319,1321,1323,1325,1328],{"class":295,"line":523},[293,1315,839],{"class":299},[293,1317,1318],{"class":422}," setup",[293,1320,426],{"class":303},[293,1322,404],{"class":416},[293,1324,237],{"class":303},[293,1326,1327],{"class":307},"setupOptions",[293,1329,466],{"class":303},[293,1331,1332,1335,1337,1339,1341,1343,1345],{"class":295,"line":543},[293,1333,1334],{"class":422},"  afterEach",[293,1336,528],{"class":303},[293,1338,435],{"class":299},[293,1340,518],{"class":416},[293,1342,237],{"class":303},[293,1344,1009],{"class":422},[293,1346,540],{"class":303},[293,1348,1349],{"class":295,"line":548},[293,1350,392],{"emptyLinePlaceholder":391},[293,1352,1353,1356,1358,1361,1363,1365,1367,1369],{"class":295,"line":568},[293,1354,1355],{"class":422},"  it",[293,1357,426],{"class":303},[293,1359,1360],{"class":321},"'uses the same session for API requests and pages'",[293,1362,261],{"class":303},[293,1364,429],{"class":299},[293,1366,432],{"class":303},[293,1368,435],{"class":299},[293,1370,438],{"class":303},[293,1372,1373,1376,1379,1381,1383,1385,1387,1389,1391,1393,1395,1398],{"class":295,"line":591},[293,1374,1375],{"class":299},"    const",[293,1377,1378],{"class":403}," user",[293,1380,576],{"class":409},[293,1382,413],{"class":299},[293,1384,518],{"class":416},[293,1386,237],{"class":303},[293,1388,1003],{"class":422},[293,1390,1084],{"class":303},[293,1392,681],{"class":307},[293,1394,281],{"class":479},[293,1396,1397],{"class":321}," 'Test viewer'",[293,1399,1400],{"class":303}," })\n",[293,1402,1403,1405,1407,1410,1412,1415,1417,1419,1421,1423,1425,1427,1429,1431,1433,1435,1437,1440],{"class":295,"line":620},[293,1404,1375],{"class":299},[293,1406,304],{"class":303},[293,1408,1409],{"class":403},"headers",[293,1411,261],{"class":303},[293,1413,1414],{"class":403},"cookies",[293,1416,315],{"class":303},[293,1418,410],{"class":409},[293,1420,413],{"class":299},[293,1422,518],{"class":416},[293,1424,237],{"class":303},[293,1426,1006],{"class":422},[293,1428,1084],{"class":303},[293,1430,762],{"class":307},[293,1432,281],{"class":479},[293,1434,1378],{"class":416},[293,1436,237],{"class":303},[293,1438,1439],{"class":307},"id",[293,1441,1400],{"class":303},[293,1443,1444,1446,1449,1451,1453,1456,1458,1461,1464,1466],{"class":295,"line":625},[293,1445,1375],{"class":299},[293,1447,1448],{"class":403}," me",[293,1450,576],{"class":409},[293,1452,413],{"class":299},[293,1454,1455],{"class":422}," $fetch",[293,1457,426],{"class":303},[293,1459,1460],{"class":321},"'\u002Fapi\u002Fme'",[293,1462,1463],{"class":303},", { ",[293,1465,1409],{"class":416},[293,1467,1400],{"class":303},[293,1469,1470,1473,1475,1478,1480,1482,1484,1486,1489,1492,1494,1496,1498,1500],{"class":295,"line":644},[293,1471,1472],{"class":422},"    expect",[293,1474,426],{"class":303},[293,1476,1477],{"class":416},"me",[293,1479,237],{"class":303},[293,1481,260],{"class":307},[293,1483,237],{"class":303},[293,1485,1439],{"class":307},[293,1487,1488],{"class":303},").",[293,1490,1491],{"class":422},"toBe",[293,1493,426],{"class":303},[293,1495,260],{"class":416},[293,1497,237],{"class":303},[293,1499,1439],{"class":307},[293,1501,466],{"class":303},[293,1503,1504],{"class":295,"line":658},[293,1505,392],{"emptyLinePlaceholder":391},[293,1507,1508,1510,1513,1515,1517,1520],{"class":295,"line":668},[293,1509,1375],{"class":299},[293,1511,1512],{"class":403}," browser",[293,1514,576],{"class":409},[293,1516,413],{"class":299},[293,1518,1519],{"class":422}," getBrowser",[293,1521,641],{"class":303},[293,1523,1524,1526,1529,1531,1533,1535,1537,1540],{"class":295,"line":702},[293,1525,1375],{"class":299},[293,1527,1528],{"class":403}," context",[293,1530,576],{"class":409},[293,1532,413],{"class":299},[293,1534,1512],{"class":416},[293,1536,237],{"class":303},[293,1538,1539],{"class":422},"newContext",[293,1541,641],{"class":303},[293,1543,1544,1547],{"class":295,"line":734},[293,1545,1546],{"class":299},"    try",[293,1548,438],{"class":303},[293,1550,1551,1554,1556,1558,1561,1563,1565],{"class":295,"line":740},[293,1552,1553],{"class":299},"      await",[293,1555,1528],{"class":416},[293,1557,237],{"class":303},[293,1559,1560],{"class":422},"addCookies",[293,1562,426],{"class":303},[293,1564,1414],{"class":416},[293,1566,466],{"class":303},[293,1568,1569,1572,1575,1577,1579,1581,1583,1586],{"class":295,"line":750},[293,1570,1571],{"class":299},"      const",[293,1573,1574],{"class":403}," page",[293,1576,576],{"class":409},[293,1578,413],{"class":299},[293,1580,1528],{"class":416},[293,1582,237],{"class":303},[293,1584,1585],{"class":422},"newPage",[293,1587,641],{"class":303},[293,1589,1590,1592,1594,1596,1599,1601,1603,1605,1608],{"class":295,"line":771},[293,1591,1553],{"class":299},[293,1593,1574],{"class":416},[293,1595,237],{"class":303},[293,1597,1598],{"class":422},"goto",[293,1600,426],{"class":303},[293,1602,1165],{"class":422},[293,1604,426],{"class":303},[293,1606,1607],{"class":321},"'\u002Fprotected'",[293,1609,1610],{"class":303},"))\n",[293,1612,1613,1616,1618,1621,1623,1625,1628,1630,1633,1635,1638,1640,1642,1644,1646],{"class":295,"line":791},[293,1614,1615],{"class":422},"      expect",[293,1617,426],{"class":303},[293,1619,1620],{"class":299},"await",[293,1622,1574],{"class":416},[293,1624,237],{"class":303},[293,1626,1627],{"class":422},"getByText",[293,1629,426],{"class":303},[293,1631,1632],{"class":321},"'Test viewer'",[293,1634,1488],{"class":303},[293,1636,1637],{"class":422},"textContent",[293,1639,607],{"class":303},[293,1641,1491],{"class":422},[293,1643,426],{"class":303},[293,1645,1632],{"class":321},[293,1647,466],{"class":303},[293,1649,1650],{"class":295,"line":825},[293,1651,1652],{"class":303},"    }\n",[293,1654,1655,1658],{"class":295,"line":830},[293,1656,1657],{"class":299},"    finally",[293,1659,438],{"class":303},[293,1661,1662,1664,1666,1668,1671],{"class":295,"line":836},[293,1663,1553],{"class":299},[293,1665,1528],{"class":416},[293,1667,237],{"class":303},[293,1669,1670],{"class":422},"close",[293,1672,641],{"class":303},[293,1674,1675],{"class":295,"line":847},[293,1676,1652],{"class":303},[293,1678,1679],{"class":295,"line":871},[293,1680,833],{"class":303},[293,1682,1683],{"class":295,"line":876},[293,1684,491],{"class":303},[222,1686,1687,1688,1691,1692,978,1695,1698],{},"This example assumes ",[234,1689,1690],{},"\u002Fapi\u002Fme"," returns ",[234,1693,1694],{},"requireUserSession(event)",[234,1696,1697],{},"\u002Fprotected"," displays the user's name. These are real persisted sessions, so server middleware, SSR, hydration, and sign-out use normal authentication. The helpers skip signup and password entry.",[222,1700,1701,1702,1705,1706,1708],{},"Create one auth context per test suite. ",[234,1703,1704],{},"clear()"," deletes users created by that context and their sessions; call it after each test, and do not run tests sharing that context concurrently. ",[234,1707,1006],{}," only accepts users created through the same context. Close browser contexts separately.",[222,1710,1711,1712,1715,1716,1719,1720,1723,1724,1727,1728,1730,1731,261,1734,261,1737,268,1740,1743],{},"The bridge is installed only by ",[234,1713,1714],{},"auth.setupOptions"," in a test build and requires a random token kept in private runtime config. Ordinary builds do not register it. Use this setup for local test fixtures, not deployed previews or production. It requires a local server and does not support ",[234,1717,1718],{},"clientOnly"," mode. The helper overrides ",[234,1721,1722],{},"NUXT_PUBLIC_SITE_URL"," for the test server, so an inherited application URL cannot change the cookie domain. Pass setup overrides to ",[234,1725,1726],{},"createAuthTestContext(options)",", then pass ",[234,1729,1714],{}," unchanged to Nuxt. It requires the built-server mode and rejects ",[234,1732,1733],{},"dev: true",[234,1735,1736],{},"host",[234,1738,1739],{},"build: false",[234,1741,1742],{},"server: false",". Nuxt Test Utils starts dev servers in a separate CLI process without these module overrides.",[222,1745,1746,1748,1749,1754],{},[234,1747,1006],{}," forwards Better Auth's supported login options. Custom session field overrides depend on ",[226,1750,1753],{"href":1751,"rel":1752},"https:\u002F\u002Fgithub.com\u002Fbetter-auth\u002Fbetter-auth\u002Fpull\u002F11217",[230],"Better Auth #11217","; they are not available in Better Auth 1.7.3. Session fields with configured defaults work with the current release.",[1756,1757],"read-more",{"title":1758,"to":228},"Nuxt Testing Guide",[1760,1761,1762],"style",{},"html pre.shiki code .sqe1H, html code.shiki .sqe1H{--shiki-light:#A626A4;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .s17Py, html code.shiki .s17Py{--shiki-light:#383A42;--shiki-default:#BBBBBB;--shiki-dark:#BBBBBB}html pre.shiki code .sYvLG, html code.shiki .sYvLG{--shiki-light:#E45649;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sPAZv, html code.shiki .sPAZv{--shiki-light:#50A14F;--shiki-default:#FF8B39;--shiki-dark:#FF8B39}html pre.shiki code .s6Rhl, html code.shiki .s6Rhl{--shiki-light:#986801;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sQBpM, html code.shiki .sQBpM{--shiki-light:#0184BC;--shiki-default:#FFFFFFEE;--shiki-dark:#FFFFFFEE}html pre.shiki code .svFNh, html code.shiki .svFNh{--shiki-light:#383A42;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sfT9l, html code.shiki .sfT9l{--shiki-light:#4078F2;--shiki-default:#36F9F6;--shiki-dark:#36F9F6}html pre.shiki code .sn-Jc, html code.shiki .sn-Jc{--shiki-light:#0184BC;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .sVnqq, html code.shiki .sVnqq{--shiki-light:#0184BC;--shiki-default:#B6B1B1;--shiki-dark:#B6B1B1}html pre.shiki code .s3ZNE, html code.shiki .s3ZNE{--shiki-light:#986801;--shiki-default:#F97E72;--shiki-dark:#F97E72}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sKg8T, html code.shiki .sKg8T{--shiki-light:#E45649;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}",{"title":289,"searchDepth":325,"depth":325,"links":1764},[1765,1766],{"id":241,"depth":325,"text":242},{"id":985,"depth":325,"text":986},"Mock reactive sessions in Nuxt component tests and create real sessions for end-to-end tests.","md",null,{},{"title":108,"description":1767},"DJeEw0ikOXERSjyHHpfUlSP3-0C-ir-Bx0__OjU1hAw",[1774,1776],{"title":104,"path":105,"stem":106,"description":1775,"children":-1},"Enable two-factor auth using the Better Auth two-factor plugin.",{"title":112,"path":113,"stem":114,"description":1777,"children":-1},"Checklist and best practices for deploying Nuxt Better Auth in production.",1792532579318]