4
0

enabledExpression.mjs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { describe, it, before, after } from 'mocha'
  2. import { expect } from 'chai'
  3. import { By, until, Condition } from 'selenium-webdriver'
  4. import {
  5. getRootAndWait,
  6. takeScreenshotOnFailure,
  7. } from '../../lib/elements.js'
  8. describe('config: enabledExpression', function () {
  9. this.timeout(30000) // Increase timeout for async operations
  10. before(async function () {
  11. await runner.start('enabledExpression')
  12. })
  13. after(async () => {
  14. await runner.stop()
  15. })
  16. afterEach(function () {
  17. takeScreenshotOnFailure(this.currentTest, webdriver);
  18. });
  19. it('Action with enabledExpression for lights enable the correct action', async function() {
  20. await getRootAndWait()
  21. // Navigate to the Lights Dashboard
  22. // Use the path with space encoded as %20 - Vue Router should decode it
  23. await webdriver.get(runner.baseUrl() + '/dashboards/LightDashboard')
  24. // Wait for the URL to change and the route to be processed
  25. await webdriver.wait(new Condition('wait for URL to contain dashboards', async function() {
  26. const url = await webdriver.getCurrentUrl()
  27. return url.includes('/dashboards/')
  28. }), 5000)
  29. // Wait for dashboard to load by checking the loaded-dashboard attribute
  30. // The attribute should be set to the decoded title "LightDashboard"
  31. await webdriver.wait(new Condition('wait for loaded-dashboard', async function() {
  32. const body = await webdriver.findElement(By.tagName('body'))
  33. const attr = await body.getAttribute('loaded-dashboard')
  34. if (attr) {
  35. console.log('Current loaded-dashboard attribute:', attr)
  36. }
  37. // Accept either decoded or encoded version (component should decode, but handle both)
  38. return attr === 'LightDashboard'
  39. }), 3000)
  40. // Verify we got the correct dashboard (prefer decoded, but accept encoded)
  41. const body = await webdriver.findElement(By.tagName('body'))
  42. const attr = await body.getAttribute('loaded-dashboard')
  43. if (attr !== 'LightDashboard') {
  44. const currentUrl = await webdriver.getCurrentUrl()
  45. throw new Error(`Dashboard not loaded correctly. Expected "LightDashboard", got "${attr}". Current URL: ${currentUrl}`)
  46. }
  47. // Wait for dashboard content to appear - check for dashboard rows first
  48. await webdriver.wait(until.elementsLocated(By.css('.dashboard-row')), 5000)
  49. // Debug: Check what's on the page
  50. const dashboardRows = await webdriver.findElements(By.css('.dashboard-row'))
  51. console.log(`Found ${dashboardRows.length} dashboard rows`)
  52. for (let i = 0; i < dashboardRows.length; i++) {
  53. const row = dashboardRows[i]
  54. const h2Elements = await row.findElements(By.css('h2'))
  55. if (h2Elements.length > 0) {
  56. const h2Text = await h2Elements[0].getText()
  57. console.log(`Row ${i} h2: "${h2Text}"`)
  58. }
  59. const fieldsets = await row.findElements(By.css('fieldset'))
  60. console.log(`Row ${i} has ${fieldsets.length} fieldsets`)
  61. if (fieldsets.length > 0) {
  62. const buttons = await fieldsets[0].findElements(By.css('.action-button button'))
  63. console.log(`Row ${i} fieldset has ${buttons.length} buttons`)
  64. }
  65. }
  66. // Find buttons by looking within entity fieldsets
  67. // Both rows have h2 title "Light Controls", so we identify them by which buttons are enabled
  68. // Living Room Light (powered_on: false) - Turn On should be enabled, Turn Off disabled
  69. // Bedroom Light (powered_on: true) - Turn Off should be enabled, Turn On disabled
  70. let turnOnButton = null
  71. let turnOffButton = null
  72. for (const row of dashboardRows) {
  73. // Get the fieldset in this row
  74. const fieldsets = await row.findElements(By.css('fieldset'))
  75. if (fieldsets.length === 0) continue
  76. const buttons = await fieldsets[0].findElements(By.css('.action-button button'))
  77. // Check each button to identify which entity this row represents
  78. for (const btn of buttons) {
  79. const title = await btn.getAttribute('title')
  80. const disabled = await btn.getAttribute('disabled')
  81. const isEnabled = disabled === null
  82. if (title === 'Turn On Light' && isEnabled) {
  83. // This is the Living Room Light row (Turn On is enabled because powered_on: false)
  84. turnOnButton = btn
  85. }
  86. if (title === 'Turn Off Light' && isEnabled) {
  87. // This is the Bedroom Light row (Turn Off is enabled because powered_on: true)
  88. turnOffButton = btn
  89. }
  90. }
  91. }
  92. expect(turnOnButton).to.not.be.null
  93. expect(turnOffButton).to.not.be.null
  94. // Check that Turn On button is enabled (light is off)
  95. const turnOnDisabled = await turnOnButton.getAttribute('disabled')
  96. expect(turnOnDisabled).to.be.null
  97. // Check that Turn Off button is enabled (light is on)
  98. const turnOffDisabled = await turnOffButton.getAttribute('disabled')
  99. expect(turnOffDisabled).to.be.null
  100. })
  101. it('Action without enabledExpression is always enabled', async function() {
  102. await getRootAndWait()
  103. // Navigate to actions view
  104. await webdriver.get(runner.baseUrl())
  105. // Wait for action buttons
  106. await webdriver.wait(until.elementLocated(By.css('.action-button')), 3000)
  107. // Find "Always Enabled Action" button
  108. const actionButtons = await webdriver.findElements(By.css('.action-button button'))
  109. let alwaysEnabledButton = null
  110. for (const btn of actionButtons) {
  111. const title = await btn.getAttribute('title')
  112. if (title === 'Always Enabled Action') {
  113. alwaysEnabledButton = btn
  114. break
  115. }
  116. }
  117. expect(alwaysEnabledButton).to.not.be.null
  118. // Check that it's enabled
  119. const disabled = await alwaysEnabledButton.getAttribute('disabled')
  120. expect(disabled).to.be.null
  121. })
  122. })