/// /** * InfluxDB Version Detector E2E Test Suite * * COMPREHENSIVE TEST SCENARIOS CHECKLIST: * * URL Detection Scenarios: * ------------------------- * Cloud URLs (Definitive Detection): * - [ ] Dedicated: https://cluster-id.influxdb.io → InfluxDB Cloud Dedicated (confidence 1.0) * - [ ] Serverless US: https://us-east-1-1.aws.cloud2.influxdata.com → InfluxDB Cloud Serverless * - [ ] Serverless EU: https://eu-central-1-1.aws.cloud2.influxdata.com → InfluxDB Cloud Serverless * - [ ] Cloud TSM: https://us-west-2-1.aws.cloud2.influxdata.com → InfluxDB Cloud v2 (TSM) * - [ ] Cloud v1: https://us-west-1-1.influxcloud.net → InfluxDB Cloud v1 * * Localhost URLs (Port-based Detection): * - [ ] Core/Enterprise Port: http://localhost:8181 → Should suggest ping test * - [ ] OSS Port: http://localhost:8086 → Should suggest version check * - [ ] Custom Port: http://localhost:9999 → Should fall back to questionnaire * * Edge Cases: * - [ ] Empty URL: Submit without entering URL → Should show error * - [ ] Invalid URL: "not-a-url" → Should fall back to questionnaire * - [ ] Cloud keyword: "cloud 2" → Should start questionnaire with cloud context * - [ ] Mixed case: HTTP://LOCALHOST:8181 → Should detect port correctly * * Airgapped/Manual Analysis Scenarios: * ------------------------------------- * Ping Headers Analysis: * - [ ] v3 Core headers: x-influxdb-build: core → InfluxDB 3 Core * - [ ] v3 Enterprise headers: x-influxdb-build: enterprise → InfluxDB 3 Enterprise * - [ ] v2 OSS headers: X-Influxdb-Version: 2.7.8 → InfluxDB OSS 2.x * - [ ] v1 headers: X-Influxdb-Version: 1.8.10 → InfluxDB OSS 1.x * - [ ] 401 Response: Headers showing 401/403 → Should show auth required message * - [ ] Empty headers: Submit without text → Should show error * - [ ] Example content: Submit with placeholder text → Should show error * * Docker Output Analysis: * - [ ] Explicit v3 Core: "InfluxDB 3 Core" in output → InfluxDB 3 Core * - [ ] Explicit v3 Enterprise: "InfluxDB 3 Enterprise" in output → InfluxDB 3 Enterprise * - [ ] Generic v3: x-influxdb-version: 3.1.0 but no build header → Core or Enterprise * - [ ] v2 version: "InfluxDB v2.7.8" in output → InfluxDB OSS 2.x * - [ ] v1 OSS: "InfluxDB v1.8.10" in output → InfluxDB OSS 1.x * - [ ] v1 Enterprise: "InfluxDB 1.8.10" + "Enterprise" → InfluxDB Enterprise * - [ ] Empty output: Submit without text → Should show error * - [ ] Example content: Submit with placeholder text → Should show error * * Questionnaire Flow Scenarios: * ------------------------------ * License-based Paths: * - [ ] Free → Self-hosted → Recent → SQL → Should rank Core/OSS highly * - [ ] Paid → Self-hosted → Recent → SQL → Should rank Enterprise highly * - [ ] Free → Cloud → Recent → Flux → Should rank Cloud Serverless/TSM * - [ ] Paid → Cloud → Recent → SQL → Should rank Dedicated highly * - [ ] Unknown license → Should not eliminate products * * Age-based Scoring: * - [ ] Recent (< 1 year) → Should favor v3 products * - [ ] 1-5 years → Should favor v2 era products * - [ ] 5+ years → Should favor v1 products only * - [ ] Unknown age → Should not affect scoring * * Language-based Elimination: * - [ ] SQL only → Should eliminate v1, v2, Cloud TSM * - [ ] Flux only → Should eliminate v1, all v3 products * - [ ] InfluxQL only → Should favor v1, but not eliminate others * - [ ] Multiple languages → Should not eliminate products * - [ ] Unknown language → Should not affect scoring * * Combined Detection Scenarios: * ----------------------------- * URL + Questionnaire: * - [ ] Port 8181 + Free license → Should show Core as high confidence * - [ ] Port 8181 + Paid license → Should show Enterprise as high confidence * - [ ] Port 8086 + Free + Recent + SQL → Mixed signals, show ranked results * - [ ] Cloud URL pattern + Paid → Should favor Dedicated/Serverless * * UI/UX Scenarios: * ---------------- * Navigation: * - [ ] Back button: From URL input → Should return to "URL known" question * - [ ] Back button: From questionnaire Q2 → Should return to Q1 * - [ ] Back button: From first question → Should stay at first question * - [ ] Progress bar: Should update with each question * * Results Display: * - [ ] High confidence (score > 60): Should show "Most Likely" label * - [ ] Medium confidence (30-60): Should show confidence rating * - [ ] Low confidence (< 30): Should show multiple candidates * - [ ] Score gap ≥ 15: Top result should stand out * - [ ] Score gap < 15: Should show multiple options * * Interactive Elements: * - [ ] Start questionnaire button: From detection results → Should hide results and start questions * - [ ] Restart button: Should clear all answers and return to start * - [ ] Grafana links: Should display for detected products * - [ ] Configuration guidance: Should display for top results * - [ ] Quick reference table: Should expand/collapse * * Pre-filled Values: * - [ ] Stored URL: Should pre-fill URL input from localStorage * - [ ] URL indicator: Should show when URL is pre-filled * - [ ] Clear indicator: Should hide when user edits URL * * Analytics Tracking Scenarios: * ----------------------------- * - [ ] Modal opened: Track when component initializes * - [ ] Question answered: Track each answer with question_id and value * - [ ] URL detection: Track with detection_method: "url_analysis" * - [ ] Product detected: Track with detected_product and completion_status * - [ ] Restart: Track restart action * * Accessibility Scenarios: * ------------------------ * - [ ] Keyboard navigation: Tab through buttons and inputs * - [ ] Focus management: Should focus on heading after showing result * - [ ] Screen reader: Labels and ARIA attributes present * - [ ] Color contrast: Results visible in different themes * * Error Handling: * --------------- * - [ ] Missing products data: Component should handle gracefully * - [ ] Missing influxdb_urls data: Should use fallback values * - [ ] Invalid JSON in data attributes: Should log warning and continue * * Edge Cases: * ----------- * - [ ] Modal initialization: Component in modal should wait for modal to open * - [ ] Multiple instances: Each instance should work independently * - [ ] Page navigation: State should persist if using back button * - [ ] URL query params: Should update with detection results */ const modalTriggerSelector = 'a.btn.influxdb-detector-trigger'; describe('InfluxDB Version Detector Component', function () { // Remove the global beforeEach to optimize for efficient running // Each describe block will visit the page once describe('Component Data Attributes', function () { beforeEach(() => { cy.visit('/test-version-detector/'); // The trigger is an anchor element with .btn class, not a button cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click(); }); it('should not throw JavaScript console errors', function () { cy.window().then((win) => { const logs = []; const originalError = win.console.error; win.console.error = (...args) => { logs.push(args.join(' ')); originalError.apply(win.console, args); }; cy.wait(2000); cy.then(() => { const relevantErrors = logs.filter( (log) => log.includes('influxdb-version-detector') || log.includes('detectContext is not a function') || log.includes('Failed to parse influxdb_urls data') ); expect(relevantErrors).to.have.length(0); }); }); }); }); describe('URL with port 8086', function () { before(() => { cy.visit('/test-version-detector/'); cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click(); cy.get('[data-component="influxdb-version-detector"]') .eq(0) .within(() => { cy.get('.option-button').contains('Yes, I know the URL').click(); it('should suggest legacy editions for custom URL or hostname', function () { cy.get('#url-input', { timeout: 10000 }) .clear() .type('http://willieshotchicken.com:8086'); cy.get('.submit-button').click(); cy.get('.result') .invoke('text') .then((text) => { // Should mention multiple products for port 8086 const mentionsLegacyEditions = text.includes('OSS 1.x') || text.includes('OSS 2.x') || text.includes('Enterprise'); expect(mentionsLegacyEditions).to.be.true; }); cy.get('#url-input', { timeout: 10000 }) .should('be.visible') .clear() .type('willieshotchicken.com:8086'); cy.get('.submit-button').click(); cy.get('.result') .invoke('text') .then((text) => { // Should mention multiple products const mentionsLegacyEditions = text.includes('OSS 1.x') || text.includes('OSS 2.x') || text.includes('Enterprise'); expect(mentionsLegacyEditions).to.be.true; }); }); it('should suggest OSS for localhost', function () { cy.get('#url-input', { timeout: 10000 }) .should('be.visible') .clear() .type('http://localhost:8086'); cy.get('.submit-button').click(); cy.get('.result') .invoke('text') .then((text) => { // Should mention multiple editions const mentionsLegacyOSS = text.includes('OSS 1.x') || text.includes('OSS 2.x'); expect(mentionsLegacyOSS).to.be.true; }); }); }); }); describe.skip('URL with port 8181', function () { const port8181UrlTests = [ // InfluxDB 3 Core/Enterprise URLs { url: 'http://localhost:8181', }, { url: 'https://my-server.com:8181', }, ]; port8181UrlTests.forEach(({ url }) => { it(`should detect Core and Enterprise 3 for ${url}`, function () { cy.visit('/test-version-detector/'); cy.get('body').then(($body) => { cy.get('#influxdb-url').clear().type(url); cy.get('.submit-button').click(); cy.get('.result') .invoke('text') .then((text) => { // Should mention multiple editions const mentionsCoreAndEnterprise = text.includes('InfluxDB 3 Core') && text.includes('InfluxDB 3 Enterprise'); expect(mentionsCoreAndEnterprise).to.be.true; }); }); }); }); }); describe.skip('Cloud URLs', function () { const cloudUrlTests = [ { url: 'https://us-west-2-1.aws.cloud2.influxdata.com', expectedText: 'Cloud', }, { url: 'https://us-east-1-1.aws.cloud2.influxdata.com', expectedText: 'Cloud', }, { url: 'https://eu-central-1-1.aws.cloud2.influxdata.com', expectedText: 'Cloud', }, { url: 'https://us-central1-1.gcp.cloud2.influxdata.com', expectedText: 'Cloud', }, { url: 'https://westeurope-1.azure.cloud2.influxdata.com', expectedText: 'Cloud', }, { url: 'https://eastus-1.azure.cloud2.influxdata.com', expectedText: 'Cloud', }, ]; cloudUrlTests.forEach(({ url, expectedText }) => { it(`should detect ${expectedText} for ${url}`, function () { cy.visit('/test-version-detector/'); cy.get('body').then(($body) => { cy.get('#influxdb-url').clear().type(url); cy.get('.submit-button').click(); cy.get('.result').should('be.visible').and('contain', expectedText); }); }); }); }); describe.skip('Cloud Dedicated and Clustered URLs', function () { const clusterUrlTests = [ // v3 Cloud Dedicated { url: 'https://cluster-id.a.influxdb.io', expectedText: 'Cloud Dedicated', }, { url: 'https://my-cluster.a.influxdb.io', expectedText: 'Cloud Dedicated', }, // v1 Enterprise/v3 Clustered { url: 'https://cluster-host.com', expectedText: 'Clustered' }, ]; clusterUrlTests.forEach(({ url, expectedText }) => { it(`should detect ${expectedText} for ${url}`, function () { cy.visit('/test-version-detector/'); cy.get('body').then(($body) => { cy.get('#influxdb-url').clear().type(url); cy.get('.submit-button').click(); cy.get('.result').should('be.visible').and('contain', expectedText); }); }); }); }); describe.skip('Cloud Dedicated and Clustered URLs', function () { const clusterUrlTests = [ // v3 Cloud Dedicated { url: 'https://cluster-id.a.influxdb.io', expectedText: 'Cloud Dedicated', }, { url: 'https://my-cluster.a.influxdb.io', expectedText: 'Cloud Dedicated', }, // v1 Enterprise/v3 Clustered { url: 'https://cluster-host.com', expectedText: 'Clustered' }, ]; clusterUrlTests.forEach(({ url, expectedText }) => { it(`should detect ${expectedText} for ${url}`, function () { cy.visit('/test-version-detector/'); cy.get('body').then(($body) => { cy.get('#influxdb-url').clear().type(url); cy.get('.submit-button').click(); cy.get('.result').should('be.visible').and('contain', expectedText); }); }); }); }); it('should handle cloud context detection', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Wait for URL input question to appear and then enter cloud context cy.get('#q-url-input', { timeout: 10000 }).should('be.visible'); cy.get('#url-input', { timeout: 10000 }) .should('be.visible') .clear() .type('cloud 2'); cy.get('.submit-button').click(); // Should proceed to next step - either show result or start questionnaire // Don't be too specific about what happens next, just verify it progresses cy.get('body').then(($body) => { if ($body.find('.result').length > 0) { cy.get('.result').should('be.visible'); } else { cy.get('.question.active', { timeout: 15000 }).should('be.visible'); } }); }); it('should handle v3 port detection', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Wait for URL input question to appear and then test v3 port detection (8181) cy.get('#q-url-input', { timeout: 10000 }).should('be.visible'); cy.get('#url-input', { timeout: 10000 }) .should('be.visible') .clear() .type('http://localhost:8181'); cy.get('.submit-button').click(); // Should progress to either result or questionnaire cy.get('body', { timeout: 15000 }).then(($body) => { if ($body.find('.result').length > 0) { cy.get('.result').should('be.visible'); } else { cy.get('.question.active').should('be.visible'); } }); }); }); describe.skip('Questionnaire Flow', function () { beforeEach(() => { cy.visit('/test-version-detector/'); // The trigger is an anchor element with .btn class, not a button cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click(); }); it('should start questionnaire for unknown URL', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); cy.get('.option-button').should('have.length.greaterThan', 0); }); it('should complete basic questionnaire flow', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Start questionnaire cy.get('#url-input') .should('be.visible') .clear() .type('https://test.com'); cy.get('.submit-button').click(); cy.get('.question.active', { timeout: 10000 }).should('be.visible'); // Answer questions with proper waiting for DOM updates const answers = ['Self-hosted', 'Free', '2-5 years', 'SQL']; answers.forEach((answer, index) => { cy.get('.question.active', { timeout: 10000 }).should('be.visible'); cy.get('.back-button').should('be.visible'); cy.get('.option-button').contains(answer).should('be.visible').click(); // Wait for the next question or final result if (index < answers.length - 1) { cy.get('.question.active', { timeout: 5000 }).should('be.visible'); } }); // Should show results cy.get('.result', { timeout: 10000 }).should('be.visible'); }); it('should show all products when answering "I\'m not sure" to all questions', function () { // Test fix for: Core/Enterprise disappearing with all "unknown" answers cy.get('.option-button').contains("No, I don't know the URL").click(); cy.get('.question.active', { timeout: 10000 }).should('be.visible'); // Answer "I'm not sure" to all questions for (let i = 0; i < 4; i++) { cy.get('.question.active', { timeout: 10000 }).should('be.visible'); cy.get('.option-button').contains("I'm not sure").click(); cy.wait(500); } cy.get('.result', { timeout: 10000 }).should('be.visible'); // Should show multiple products, not empty or filtered list cy.get('.result').invoke('text').should('have.length.greaterThan', 100); }); it('should NOT recommend InfluxDB 3 for Flux users (regression test)', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').should('be.visible').clear().type('cloud 2'); cy.get('.submit-button').click(); cy.get('.question.active', { timeout: 10000 }).should('be.visible'); // Complete problematic scenario that was fixed const answers = ['Paid', '2-5 years', 'Flux']; answers.forEach((answer, index) => { cy.get('.question.active', { timeout: 10000 }).should('be.visible'); cy.get('.option-button').contains(answer).should('be.visible').click(); // Wait for the next question or final result if (index < answers.length - 1) { cy.get('.question.active', { timeout: 5000 }).should('be.visible'); } }); cy.get('.result', { timeout: 10000 }).should('be.visible'); // Should NOT recommend InfluxDB 3 products for Flux cy.get('.result').should('not.contain', 'InfluxDB 3 Core'); cy.get('.result').should('not.contain', 'InfluxDB 3 Enterprise'); }); // Comprehensive questionnaire scenarios covering all decision tree paths const questionnaireScenarios = [ { name: 'SQL Filtering Test - Only InfluxDB 3 products for SQL (Free)', answers: ['Self-hosted', 'Free', 'Less than 6 months', 'SQL'], shouldContain: ['InfluxDB 3'], shouldNotContain: [ 'InfluxDB OSS 1.x', 'InfluxDB OSS 2.x', 'InfluxDB Enterprise v1.x', 'InfluxDB Cloud (TSM)', ], }, { name: 'SQL Filtering Test - Only InfluxDB 3 products for SQL (Paid)', answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL'], shouldContain: ['InfluxDB 3'], shouldNotContain: [ 'InfluxDB OSS 1.x', 'InfluxDB OSS 2.x', 'InfluxDB Enterprise v1.x', 'InfluxDB Cloud (TSM)', ], }, { name: 'SQL Filtering Test - Only InfluxDB 3 Cloud products for SQL', answers: [ 'Cloud (managed service)', 'Paid', 'Less than 6 months', 'SQL', ], shouldContain: ['Cloud'], shouldNotContain: [ 'InfluxDB OSS', 'InfluxDB Enterprise v1.x', 'InfluxDB Cloud (TSM)', ], }, { name: 'OSS Free User - SQL (recent)', answers: ['Self-hosted', 'Free', 'Less than 6 months', 'SQL'], shouldContain: ['InfluxDB 3 Core'], shouldNotContain: ['InfluxDB 3 Enterprise'], }, { name: 'OSS Free User - SQL (experienced)', answers: ['Self-hosted', 'Free', '2-5 years', 'SQL'], shouldContain: ['InfluxDB 3 Core'], shouldNotContain: ['InfluxDB 3 Enterprise'], }, { name: 'Cloud Flux User', answers: [ 'Cloud (managed service)', 'Paid', 'Less than 6 months', 'Flux', ], shouldContain: ['InfluxDB v2', 'Cloud'], shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'], }, { name: 'Cloud SQL User (recent)', answers: [ 'Cloud (managed service)', 'Paid', 'Less than 6 months', 'SQL', ], shouldContain: ['Cloud Serverless', 'Cloud Dedicated'], shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'], }, { name: 'Modern Self-hosted SQL User', answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL'], shouldContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'], shouldNotContain: ['Cloud'], }, { name: 'High Volume Enterprise User', answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL', 'Yes'], shouldContain: ['InfluxDB 3 Enterprise'], shouldNotContain: ['Cloud'], }, { name: 'Legacy Self-hosted User (InfluxQL)', answers: ['Self-hosted', 'Free', '5+ years', 'InfluxQL'], shouldContain: ['InfluxDB v1', 'OSS'], shouldNotContain: ['InfluxDB 3'], }, { name: 'Legacy Enterprise User', answers: ['Self-hosted', 'Paid', '5+ years', 'InfluxQL'], shouldContain: ['InfluxDB Enterprise', 'InfluxDB v1'], shouldNotContain: ['InfluxDB 3'], }, { name: 'Experienced OSS User (Flux)', answers: ['Self-hosted', 'Free', '2-5 years', 'Flux'], shouldContain: ['InfluxDB v2', 'OSS'], shouldNotContain: ['InfluxDB 3', 'Enterprise'], }, { name: 'Cloud Free User (recent)', answers: [ 'Cloud (managed service)', 'Free', 'Less than 6 months', 'SQL', ], shouldContain: ['Cloud Serverless'], shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'], }, { name: 'SQL Cloud User - Only InfluxDB 3 Cloud products', answers: [ 'Cloud (managed service)', 'Paid', 'Less than 6 months', 'SQL', ], shouldContain: ['Cloud Serverless', 'Cloud Dedicated'], shouldNotContain: [ 'InfluxDB OSS', 'InfluxDB Enterprise v1', 'InfluxDB Cloud (TSM)', ], }, { name: 'Uncertain User', answers: [ "I'm not sure", "I'm not sure", "I'm not sure", "I'm not sure", ], shouldContain: [], // Should still provide some recommendations shouldNotContain: [], }, ]; questionnaireScenarios.forEach((scenario) => { it(`should handle questionnaire scenario: ${scenario.name}`, function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Start questionnaire cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); // Answer questions scenario.answers.forEach((answer) => { cy.get('.question.active').should('be.visible'); cy.get('.option-button').contains(answer).click(); cy.wait(500); }); // Verify results cy.get('.result').should('be.visible'); // Check expected content scenario.shouldContain.forEach((product) => { cy.get('.result').should('contain', product); }); // Check content that should NOT be present scenario.shouldNotContain.forEach((product) => { cy.get('.result').should('not.contain', product); }); }); it('should NOT recommend InfluxDB 3 for 5+ year installations (time-aware)', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); // Test that v3 products are excluded for 5+ years const answers = ['Free', 'Self-hosted', 'More than 5 years', 'SQL']; answers.forEach((answer) => { cy.get('.question.active').should('be.visible'); cy.get('.option-button').contains(answer).click(); cy.wait(500); }); cy.get('.result').should('be.visible'); cy.get('.result').should('not.contain', 'InfluxDB 3 Core'); cy.get('.result').should('not.contain', 'InfluxDB 3 Enterprise'); // Should recommend legacy products instead cy.get('.result').should('contain', 'InfluxDB'); }); }); it('should apply -100 Flux penalty to InfluxDB 3 products', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); // Even for recent, paid, self-hosted users, Flux should eliminate v3 products const answers = ['Self-hosted', 'Paid', 'Less than 6 months', 'Flux']; answers.forEach((answer) => { cy.get('.question.active').should('be.visible'); cy.get('.option-button').contains(answer).click(); cy.wait(500); }); cy.get('.result').should('be.visible'); cy.get('.result').should('not.contain', 'InfluxDB 3 Core'); cy.get('.result').should('not.contain', 'InfluxDB 3 Enterprise'); }); it('should detect cloud context correctly with regex patterns', function () { const cloudPatterns = ['cloud 2', 'cloud v2', 'influxdb cloud 2']; // Test first pattern in current session cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').clear().type(cloudPatterns[0]); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); }); // Navigation and interaction tests it('should allow going back through questionnaire questions', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Start questionnaire cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); // Answer first question cy.get('.option-button').first().click(); cy.wait(500); // Check if back button exists and is clickable cy.get('body').then(($body) => { if ($body.find('.back-button').length > 0) { cy.get('.back-button').should('be.visible').click(); cy.get('.question.active').should('be.visible'); } }); }); it('should allow restarting questionnaire from results', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Complete a questionnaire cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); const answers = ['Self-hosted', 'Free', '2-5 years', 'SQL']; answers.forEach((answer) => { cy.get('.question.active').should('be.visible'); cy.get('.back-button').should('be.visible'); cy.get('.option-button').contains(answer).click(); cy.wait(500); }); cy.get('.result').should('be.visible'); // Check if restart button exists and works cy.get('body').then(($body) => { if ($body.find('.restart-button').length > 0) { cy.get('.restart-button').should('be.visible').click(); cy.get('.question.active').should('be.visible'); } }); }); }); describe.skip('Basic Error Handling', function () { beforeEach(() => { cy.visit('/test-version-detector/'); // The trigger is an anchor element with .btn class, not a button cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click(); }); it('should handle empty URL input gracefully', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').clear(); cy.get('.submit-button').click(); // Should start questionnaire or show guidance cy.get('.question.active, .result').should('be.visible'); }); it('should handle invalid URL format gracefully', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); cy.get('#url-input').clear().type('not-a-valid-url'); cy.get('.submit-button').click(); // Should handle gracefully cy.get('.question.active, .result').should('be.visible'); }); }); describe.skip('SQL Language Filtering', function () { beforeEach(() => { cy.visit('/test-version-detector/'); // The trigger is an anchor element with .btn class, not a button cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click(); }); it('should only show InfluxDB 3 products when SQL is selected', function () { // Click "Yes, I know the URL" first cy.get('.option-button').contains('Yes, I know the URL').click(); // Start questionnaire with unknown URL cy.get('#url-input').clear().type('https://unknown-server.com:9999'); cy.get('.submit-button').click(); cy.get('.question.active').should('be.visible'); // Answer questions leading to SQL selection const answers = ['Self-hosted', 'Free', 'Less than 6 months', 'SQL']; answers.forEach((answer) => { cy.get('.question.active').should('be.visible'); cy.get('.option-button').contains(answer).click(); cy.wait(500); }); cy.get('.result').should('be.visible'); // Get the full result text to verify filtering cy.get('.result') .invoke('text') .then((resultText) => { // Verify that ONLY InfluxDB 3 products are shown const shouldNotContain = [ 'InfluxDB Enterprise v1.x', 'InfluxDB OSS v2.x', 'InfluxDB OSS 1.x', 'InfluxDB Cloud (TSM)', ]; // Check that forbidden products are NOT in results shouldNotContain.forEach((forbiddenProduct) => { expect(resultText).to.not.contain(forbiddenProduct); }); // Verify at least one InfluxDB 3 product is shown const hasValidProduct = resultText.includes('InfluxDB 3 Core') || resultText.includes('Cloud Dedicated') || resultText.includes('Cloud Serverless') || resultText.includes('InfluxDB Clustered'); expect(hasValidProduct).to.be.true; }); }); }); });