Historial de navegación sembrado: sesión y global
Qué distingue el historial sembrado de la navegación con scripts, de reutilizar el directorio de datos y de history.pushState, y por qué history.length no es el historial global.
BotBrowser Team
Prefieres la documentación del producto mantenida?
Este artículo tiene una página equivalente en el centro de documentación. Usa los docs para el flujo canónico, las flags actuales y la referencia duradera.
Una sesión de navegador recién iniciada tiene un pasado muy corto. La pestaña guarda una sola entrada en su pila de retroceso y avance, la barra de direcciones no tiene nada que sugerir y la página de historial puede estar vacía. Los equipos que ejecutan pruebas de navegador repetibles a veces quieren partir de otro estado: una sesión que ya tenga cierta profundidad de navegación, para que el código bajo prueba encuentre las mismas condiciones en cada ejecución.
Ese objetivo es fácil de enunciar y fácil de resolver mal, porque dos registros distintos se llaman historial. A continuación se separan los dos registros, se comparan cuatro formas de preparar una sesión (navegación con scripts, un directorio de datos reutilizado, history.pushState y la siembra al iniciar con BotBrowser), se enumeran los modos de --bot-inject-random-history y se propone un procedimiento corto para comprobar el resultado sin confundir un registro con el otro.
Resumen
history.lengthcuenta las entradas de sesión de una pestaña; no expone la lista de todo el perfil que muestrachrome://history.- La navegación con scripts crea URL, redirecciones, cookies y almacenamiento elegidos.
history.pushState()solo modifica la pila de sesión de la pestaña actual. --bot-inject-random-history=<count>fija la profundidad de sesión al iniciar para comprobar una rama de forma repetible, pero no elige URL visitadas ni reproduce el estado de un sitio.
Contenido de esta guía
- Dos historiales detrás de una palabra
- Cuatro formas de preparar una sesión
- Modos de la marca de siembra
- Cómo elegir el enfoque para una prueba
- Comprobar qué ha ocurrido de verdad
- Conclusión práctica
Dos historiales detrás de una palabra
Los navegadores usan la palabra historial para al menos dos registros distintos, y la mayor parte de la confusión sobre el historial sembrado nace de mezclarlos.
El primer registro es el historial de sesión. Cada pestaña guarda una lista ordenada de las páginas que ha mostrado, y los botones de retroceso y avance recorren esa lista. Los scripts de la página llegan a ella mediante la interfaz History. Según MDN, history.length es un entero de solo lectura que contiene el número de entradas del historial de sesión, incluida la página cargada en ese momento, y una página abierta en una pestaña nueva devuelve 1. Llamar a history.back(), history.forward() o history.go() recorre la lista, mientras que history.pushState() y history.replaceState() la modifican sin cargar un documento nuevo.
El segundo registro es el historial global. Es la lista de direcciones visitadas de todo el navegador que alimenta la página chrome://history y las sugerencias de la barra de direcciones, que Chromium llama omnibox. Se guarda junto con los datos del perfil, todas las pestañas contribuyen a él y un script de página no puede leerlo. Un número como history.length no dice nada sobre lo que contiene.
Los dos registros responden a preguntas distintas. El historial de sesión responde cuántos pasos tiene esta pestaña detrás. El historial global responde qué direcciones ha visitado este perfil. Una prueba que solo lee history.length observa el primer registro, y una prueba que abre chrome://history observa el segundo. Ninguna de las dos observaciones demuestra nada sobre el otro registro, así que una técnica que añade una entrada a la pila de retroceso no añade automáticamente una fila a la página de historial, y una técnica que llena la página de historial no cambia automáticamente el número que lee un script.
Esto importa en las pruebas porque el código de las aplicaciones lee los dos tipos de estado, de forma directa o indirecta. Una aplicación de una sola página puede mostrar su propio botón de volver solo cuando history.length es mayor que 1. Un flujo de inicio de sesión puede decidir adónde enviar al visitante según exista o no una entrada anterior. Quien prueba a mano ve sugerencias distintas en la barra de direcciones cuando el perfil ya tiene algo de pasado. Si un entorno de pruebas arranca siempre con el pasado más corto posible, la prueba solo recorre la rama de primera visita de ese código. Sembrar te da una forma de ejecutar la otra rama a propósito.
Hay otra propiedad del historial de sesión que se olvida con facilidad: pertenece a una sola pestaña. Una ventana emergente, una segunda pestaña o una ventana recién abierta empiezan su propia lista. Cuando una prueba lee history.length en una pestaña distinta de la preparada, lee otra lista, y el valor 1 en una pestaña nueva es el comportamiento esperado, no una señal de que la siembra haya fallado.
Cuatro formas de preparar una sesión
Hay cuatro formas habituales de dar algo de historial a una sesión antes de que empiece la prueba real. Se diferencian en el registro que tocan, en los efectos secundarios que causan y en lo repetibles que son.
Navegación con scripts
El método más directo es visitar páginas. El script anota la URL HTTP, el destino final de cada redirección y history.length tras cada navegación, y después empieza el trabajo real. Es el único método de la lista que produce estado real de página: las direcciones visitadas son exactamente las que elegiste, las redirecciones se registran tal como las sirvió el sitio, y las cookies y el almacenamiento los rellenan los propios sitios. También es el método más costoso.
- Tiempo. Cada página tiene que cargar, así que la preparación tarda de varios segundos a minutos, según las páginas y la conexión.
- Tráfico de red. Cada visita envía solicitudes reales, consume el ancho de banda de la ruta que use el navegador y puede topar con límites de frecuencia.
- Efectos secundarios. Las páginas ejecutan sus propios scripts, establecen cookies y envían eventos de analítica antes de que empiece la prueba, de modo que esta ya no parte de un estado limpio.
- Variación. Los tiempos de carga, las redirecciones y el contenido dinámico cambian entre ejecuciones, por lo que el historial resultante no es el mismo de una ejecución a otra.
Usa la navegación con scripts cuando la prueba dependa de direcciones visitadas concretas o de estado real de página. Nada más de esta lista puede ofrecer ninguna de las dos cosas.
Reutilizar un directorio de datos de usuario
Apuntar cada inicio al mismo --user-data-dir conserva lo que guardó la ejecución anterior, incluida su base de datos de historial global. El precio es que conserva también todo lo demás: cookies, almacenamiento local, archivos en caché y service workers. No puedes llevar solo el historial y reiniciar el resto.
La prueba deja además de ser estrictamente repetible, porque el estado inicial es lo que dejó la última ejecución. La ejecución N depende entonces de las ejecuciones 1 a N-1. Copiar el directorio desde una instantánea conocida antes de cada ejecución elimina la deriva, a costa de manejar archivos y ocupar disco. Este enfoque encaja con pruebas que de verdad tratan de estado de larga duración. Es una forma pesada de conseguir una profundidad de historial.
Llamar a history.pushState
Un script de página puede llamar a history.pushState(state, '', url) para añadir una entrada al historial de sesión de la pestaña sin cargar nada. MDN señala que la nueva URL debe tener el mismo origen que la actual, de modo que un script de un sitio no puede llenar la pila con direcciones de otros sitios, y MDN describe la llamada solo en términos de la pila del historial de sesión.
La llamada es una API de página pensada para aplicaciones de una sola página. No sirve para construir un registro de navegación. En una prueba es útil para una sola cosa: reproducir cómo una aplicación de una sola página hace crecer su propia pila de retroceso, para comprobar cómo reacciona tu código cuando history.length sube sin ninguna carga de página.
Sembrar al iniciar
La marca --bot-inject-random-history de BotBrowser (nivel PRO) toma otro camino. En lugar de visitar páginas, crea entradas sintéticas al arrancar, antes de que cargue la primera página. Como las entradas se generan al arrancar en lugar de cargarse desde sitios, la preparación no necesita cargas de página con scripts. Como el número lo controla la marca, dos inicios con el mismo valor parten de la misma profundidad.
La documentación también indica el alcance con claridad: la inyección se aplica a cada sesión nueva y las entradas inyectadas no persisten más allá de la vida de la sesión. Lo que la marca no permite es elegir las direcciones. Las entradas se generan por ti.
Modos de la marca de siembra
La documentación de siembra de historial de BotBrowser enumera dos formas de activar la marca y una de desactivarla.
--bot-inject-random-historyo--bot-inject-random-history=truees el modo aleatorio. Inyecta un número aleatorio de entradas de 2 a 7, lo que según la documentación da unhistory.lengthde 3 a 8.--bot-inject-random-history=15es el modo exacto. Inyecta exactamente esa cantidad de entradas, de modo quehistory.lengthes la cantidad más uno: 15 entradas dan 16 en la primera página. La documentación indica que el valor debe estar entre 1 y 25.--bot-inject-random-history=falsedesactiva la inyección.
El mismo ajuste puede venir de la configuración del perfil mediante la clave injectRandomHistory, donde true elige el modo aleatorio y un número elige el modo exacto. Cuando están presentes ambos, la marca de la línea de comandos prevalece sobre el perfil.
# Modo aleatorio: de 2 a 7 entradas
chromium-browser --bot-profile="path/to/profile.enc" --bot-inject-random-history
# Modo exacto: 15 entradas, history.length vale 16 en la primera página
chromium-browser --bot-profile="path/to/profile.enc" --bot-inject-random-history=15
Dos propiedades del modo exacto importan para la repetibilidad. La aritmética es lo bastante simple como para afirmarla en una prueba: el valor esperado en la primera página es la cantidad más uno. Y el modo aleatorio da un rango, así que una aserción debe aceptar de 3 a 8 en lugar de un solo número. Si una prueba necesita un único valor, usa el modo exacto y escribe la cantidad en el comando de inicio.
Como las entradas se generan y el alcance es la sesión, trata cada inicio como una siembra nueva. No esperes que las entradas de la ejecución de ayer estén esperando en un directorio de datos reutilizado. Guarda en cambio el valor de la marca en el comando de inicio de cada ejecución, para que la profundidad inicial quede escrita junto a la prueba.
La marca se combina con las demás opciones de siembra de la documentación, como --bot-cookies y --bot-bookmarks. Consulta Gestión de cookies e Inyección de marcadores para ellas, y Gestión de perfiles para mantener ordenados los conjuntos de perfiles. Para varios contextos de navegador dentro de un mismo navegador, la documentación lista el historial por contexto como una función ENT Tier3.
Cómo elegir el enfoque para una prueba
Elige el enfoque según la pregunta que plantea la prueba. La tabla resume qué toca cada método y qué cuesta.
| Enfoque | Qué toca | Red y efectos secundarios | Repetibilidad | Elección de URL |
|---|---|---|---|---|
| Navegación con scripts | Historial de sesión e historial global | Solicitudes reales, scripts de página, cookies | Varía con los tiempos de carga y el contenido | Sí |
| Directorio de datos reutilizado | Todo lo guardado antes | Sin solicitudes nuevas, pero vuelve el estado antiguo | Depende de ejecuciones anteriores | Solo a través de ejecuciones anteriores |
history.pushState | Historial de sesión de una pestaña | Ninguno | Alta | Solo el mismo origen |
| Marca de siembra | Entradas contadas por history.length, según la documentación | Se generan al arrancar, no se cargan desde sitios | Alta en modo exacto | No |
El coste es solo una parte de la decisión. La repetibilidad es la otra, y es donde más se diferencian los métodos. Una visita con scripts depende de los sitios que visitas, un directorio reutilizado depende de ejecuciones anteriores, y una cantidad sembrada depende solo del comando de inicio. Cuando hay que explicar un fallo de prueba un mes después, un único valor en una línea de comandos es mucho más fácil de razonar que un historial construido con páginas reales. Unas cuantas situaciones muestran cómo se aplica la elección.
- Necesitas una pila de retroceso de profundidad conocida. Usa el modo exacto. El
history.lengthesperado es la cantidad más uno, y el mismo comando de inicio da el mismo punto de partida cada vez. - Necesitas algo de profundidad, pero no un número concreto. Usa el modo aleatorio y haz que las aserciones acepten el rango de 3 a 8.
- Necesitas direcciones concretas o estado real de página. Usa la navegación con scripts. Una página que lee una cookie establecida por una visita anterior, o un sitio que registra el número de visitas, solo se puede preparar visitándolos de verdad.
- Pruebas una transición de ruta de una aplicación de una sola página. Llama a
history.pushStatedentro de la prueba y verifica el manejadorpopstateque debe restaurar la vista anterior. - Necesitas que todo el estado pase de una ejecución a otra. Reutiliza una copia del directorio de datos y acepta la deriva que conlleva.
Los enfoques también se combinan. Un arreglo habitual es sembrar una profundidad con la marca y después ejecutar con scripts solo las dos o tres navegaciones de las que la prueba depende de verdad. La preparación se mantiene corta y el estado de página es real donde importa. Al combinarlos, recuerda que cada navegación con script suma al contador. Espera que history.length suba uno por cada entrada nueva sobre el valor sembrado, y mide una línea base en tu propia compilación antes de escribir aserciones exactas, porque las redirecciones y los scripts de página pueden añadir entradas que no habías previsto.
Comprobar qué ha ocurrido de verdad
La verificación debe leer los dos registros, porque cada uno dice algo distinto. Un registro de ejecución con los campos siguientes convierte una observación puntual en algo que un compañero puede repetir.
- Lee el valor de sesión. Abre una página y lee
history.lengthen la consola de las herramientas de desarrollo. Con el modo exacto y una cantidad de 15, la primera página devuelve 16, según la documentación. En modo aleatorio el valor debe quedar entre 3 y 8. - Abre
chrome://historyen la misma sesión y mira las entradas. La documentación describe el efecto sobrehistory.lengthy sobre la sesión. No describe la página de historial, así que si las entradas aparecen allí y cómo lo hacen es algo que debes observar en tu propia compilación y anotar, no algo que dar por supuesto. - Navega una vez y vuelve a leer el valor. Debe subir uno por la nueva entrada. Si no sube, comprueba si la página redirigió o reemplazó su propia entrada.
- Inicia de nuevo con las mismas marcas y repite las comprobaciones. Las entradas sembradas se aplican a cada sesión nueva, así que el modo exacto debe dar los mismos valores y el modo aleatorio debe mantenerse dentro de su rango.
- Escribe el valor de inicio junto al resultado. Anota la marca, la compilación, la longitud esperada, la longitud observada y lo que mostró la página de historial.
Escribe las aserciones como relaciones y no como números mágicos. En modo exacto, el valor esperado en la primera página es la cantidad sembrada más uno, y cada navegación posterior de la prueba suma una más. Expresar la comprobación así la mantiene correcta cuando alguien cambia la cantidad sembrada, y un fallo apunta entonces a una diferencia concreta entre el valor esperado y el observado. En modo aleatorio, afirma solo el rango documentado y anota el valor observado, para que una ejecución sorprendente se pueda entender después.
La mayoría de las comprobaciones fallidas vienen de una lista corta de errores. El primero es leer history.length en una pestaña distinta de la preparada, donde una pestaña nueva informa correctamente de 1. El segundo es comparar un valor sembrado con un número medido después de navegaciones adicionales. El tercero es esperar que las entradas sobrevivan a un reinicio, algo que la documentación dice que no ocurre. El cuarto es escribir una aserción exacta contra el modo aleatorio.
Si history.length se queda en 1, la documentación apunta a tres causas. Puede que la marca se haya pasado fuera del arreglo de argumentos del lanzador. Puede que la licencia no esté activa, en cuyo caso la salida de consola de BotBrowser informa de un error de licencia. O puede que la cantidad se haya escrito sin el signo igual, o fuera del rango permitido de 1 a 25.
Que history.length coincida solo demuestra que la sesión lleva entradas. No demuestra cómo tratará un sitio concreto esa sesión, y aquí no se hace ninguna afirmación de ese tipo. El historial sembrado es una entrada más de una sesión de prueba, junto a las cookies, los marcadores, la configuración regional y la zona horaria que configuras por separado.
Un registro por ejecución, y qué significa un diff
| Campo del registro | Para qué está |
|---|---|
flag | El valor exacto de --bot-inject-random-history o exact |
build | La cadena de compilación del navegador que usó la ejecución |
firstPageLength | history.length en la primera página, antes de navegar |
afterOneNavigation | El mismo valor tras exactamente una navegación |
historyPage | Si chrome://history listó entradas, y en qué forma |
Cinco campos bastan para distinguir un cambio real de una ejecución mal leída, pero solo si los cinco se escriben siempre. Un registro con la longitud y sin la compilación no puede distinguir «cambió la semilla» de «cambió el navegador», y esa ambigüedad es lo que vuelve inaplicable un informe de regresión.
Lee el registro comparando dos ejecuciones campo por campo, no comparando dos números aislados. Cuando solo difiere build y firstPageLength lo acompaña, la semilla se aplicó y la compilación cambió el desfase. Cuando solo difiere flag, el desfase debe moverse con él exactamente por la diferencia en el conteo sembrado si ambas ejecuciones usan un conteo exacto. Cuando firstPageLength no cambia entre dos conteos exactos distintos, la marca no llegó al proceso y el resto del registro describe el mismo lanzamiento dos veces; dos ejecuciones en modo aleatorio pueden coincidir legítimamente en la misma longitud dentro del rango documentado, así que un valor sin cambios ahí no prueba nada.
El campo de navegación es el que detecta un error de uno. Una primera página informa el conteo sembrado más uno, así que un registro cuyo afterOneNavigation iguala su firstPageLength describe una navegación que nunca se confirmó, normalmente porque la página redirigió o reemplazó su propia entrada. Eso es un hallazgo sobre el sitio y no sobre la semilla.
Deja historyPage como observación y no como aserción. La documentación no describe qué muestra la página de historial para las entradas sembradas, así que anota lo que viste junto a la compilación y deja que la siguiente persona compare. Un registro que afirmara un estado esperado codificaría una afirmación que la documentación nunca hizo.
Conclusión práctica
Dónde encaja BotBrowser y dónde termina. El historial sembrado es una parte pequeña de un plan de pruebas. Fija una variable, la profundidad de la sesión al iniciar, para que las demás variables se puedan estudiar sobre un fondo estable.
BotBrowser (PRO) soporta la siembra de historial de navegación sintético al iniciar mediante --bot-inject-random-history, ya sea con un número aleatorio de entradas o con una cantidad exacta, de modo que puedes empezar cada sesión de prueba con una profundidad de historial repetible sin cargas de página con scripts. No te permite elegir las URL inyectadas, no puede garantizar que las entradas coincidan con una configuración regional ni que parezcan uso real para un sitio concreto, y no sustituye la navegación con scripts cuando se necesitan URL visitadas concretas o estado real de la página.
Consulta la documentación actual para ver el nivel, el rango de cantidades y la redacción sobre history.length antes de apoyarte en ellos en una versión de producción, y usa la página de MDN sobre history.length como referencia para la parte de sesión del comportamiento.
Fuentes públicas
Este artículo forma parte de la guía: Superficies de identidad del navegador: panorama de coherencia
Artículos Relacionados
Inyección de marcadores: prellenar los marcadores del navegador
PlataformaNavigation API, historial y límites de privacidad
IdentidadCiclo de vida de IndexedDB: versiones, cuota y limpieza
IdentidadEvento storage: coherencia entre pestañas y límites de privacidad
Huella digitalQué hace y qué no hace la navegación privada
IdentidadPor qué el modo incógnito no protege contra el fingerprinting
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.