Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration/latest levels app2 #858

Merged
merged 78 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
56e48b4
FSR-1261: Improve visibility of map link and sign-up call to action o…
Keyurx11 Jul 22, 2024
a58925c
FSR-1261: Change map button text colour to blue
Keyurx11 Sep 18, 2024
e205453
FSR-1261: Change Icon on map button to be black
Keyurx11 Sep 18, 2024
f6a0006
FSR-1294: Add logic to wrap text for the threshold label on the stati…
Keyurx11 Sep 19, 2024
961efe6
auto refresh. updated TA tests
Sep 23, 2024
135eee6
sonar fixes
Sep 23, 2024
dc48d17
some sonar fixes
Sep 23, 2024
3b7922a
added links to flood warnings target areas in thresholds
LeeGordon83 Sep 27, 2024
e1f79cb
altered logic for top of normal range and fixed unit tests
LeeGordon83 Oct 1, 2024
15a2f92
changed chart.js threshold references
LeeGordon83 Oct 2, 2024
0460518
fixed sonar issues
LeeGordon83 Oct 2, 2024
8be10c9
refactored code to reduce complexity for Sonarcloud
LeeGordon83 Oct 3, 2024
b4fc81e
updated short name on thresholds to include name of flood warning area
LeeGordon83 Oct 3, 2024
14683b0
FSR-1333: Consistent map button CSS
Keyurx11 Sep 26, 2024
31f961a
FSR-1333: Change map button text to blue and icon to black
Keyurx11 Oct 2, 2024
6733a5c
FSR-1261: Remove additional CSS to avoid duplication in upcoming merge
Keyurx11 Oct 3, 2024
0219b84
FSR-1333: Refactor CSV download button styling for consistency with m…
Keyurx11 Oct 3, 2024
ee3e734
FSR-1295: Display correct chart thresholds based on presence of TID i…
Keyurx11 Oct 3, 2024
40ca572
removed incorrect capital letter
LeeGordon83 Oct 8, 2024
ec0d868
FSR-1295: Exclude TID in URL for Welsh stations on the latest level l…
Keyurx11 Oct 3, 2024
cf252e1
FSR-1295: Add tests
Keyurx11 Oct 4, 2024
f288a57
FSR-1295: Refactor code and fix sonar clould issues
Keyurx11 Oct 8, 2024
70cbf43
refactor autorefresh. add unit tests
Oct 9, 2024
cd49b36
conditional callback
Oct 9, 2024
33a01cc
CSS fix to handle stations with historical threshold values
LeeGordon83 Oct 9, 2024
1eedcfa
Fix/fsr 1237 latest level warning pages service (#844)
Keyurx11 Oct 9, 2024
f4ced23
Feature/fsr 1261 update ta pay layout (#845)
Keyurx11 Oct 9, 2024
35e7a1a
Merge branch 'integration/latest-levels-app' into feature/FSR-1333-Up…
Keyurx11 Oct 9, 2024
8e0ff62
use <output> element
Oct 10, 2024
ebb8b42
latest level refactor and unit tests
Oct 10, 2024
5801e62
fix test
Oct 10, 2024
c45cdd1
remove console logs
Oct 11, 2024
ecb7b01
move update in to test
Oct 11, 2024
f3acbff
added process warning thresholds functions and tests
LeeGordon83 Oct 14, 2024
54c45bd
fixing sonar issues
LeeGordon83 Oct 14, 2024
1625dc0
fixed linting issue
LeeGordon83 Oct 14, 2024
634901c
sonar fix
LeeGordon83 Oct 14, 2024
6fc7009
fixed chart label and latest levels CSS
LeeGordon83 Oct 15, 2024
12e1aba
stopped displaying inactive warnings as thresholds
LeeGordon83 Oct 15, 2024
8a71179
sonar fix
LeeGordon83 Oct 16, 2024
163c790
Merge remote-tracking branch 'origin/feature/FSR-1261-update-ta-pay-l…
LeeGordon83 Oct 16, 2024
3c7949e
Merge branch 'feature/FSR-1333-Update-Map-Buttons-Styling' into integ…
LeeGordon83 Oct 16, 2024
08bee01
Merge branch 'feature/FSR-1294-Station-Chart-Label-Wrapping' into int…
LeeGordon83 Oct 16, 2024
8ae7f7d
merged with FSR-1295
LeeGordon83 Oct 16, 2024
d20f9a5
merged with FSR-1295
LeeGordon83 Oct 16, 2024
5bec829
Merge branch 'feature/FSR-1287' into integration/latest-levels-app2
LeeGordon83 Oct 16, 2024
7f3a926
rejig of logic to show top of normal range
LeeGordon83 Oct 16, 2024
b1f76c8
sonar fixes
LeeGordon83 Oct 16, 2024
70a49b2
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 16, 2024
75b50b2
change to top of normal range value
LeeGordon83 Oct 17, 2024
cba8dc5
altered value on top of normal range
LeeGordon83 Oct 17, 2024
48878ce
sonar fix
LeeGordon83 Oct 17, 2024
75e1638
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 17, 2024
f747197
changed top of normal range to 2dp
LeeGordon83 Oct 17, 2024
5e151ce
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 17, 2024
48c17be
rejig of 2dp fix
LeeGordon83 Oct 17, 2024
affe8e4
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 17, 2024
1431e6d
altered id of top of normal range thresholds
LeeGordon83 Oct 17, 2024
5a656d3
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 17, 2024
7d592bc
roll back of _chart-controls.scss
LeeGordon83 Oct 17, 2024
0f0a390
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 17, 2024
e41de04
reload on warning change
Oct 18, 2024
28fe3cd
Merge branch 'feature/FSR-1287' into integration/latest-levels-app2
Oct 18, 2024
666dc9c
added stage datum calculations to warnings
LeeGordon83 Oct 21, 2024
e015c89
sonar fix
LeeGordon83 Oct 21, 2024
3727267
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 21, 2024
dec2ddc
bring process threshold into it's own class
LeeGordon83 Oct 21, 2024
0af8dec
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 21, 2024
be14062
removed uneeded export
LeeGordon83 Oct 21, 2024
e985dec
Merge branch 'feature/FSR-1293' into integration/latest-levels-app2
LeeGordon83 Oct 21, 2024
6896043
fix for chart label
LeeGordon83 Oct 21, 2024
7c3fda0
attempt at fixing auto refresh
LeeGordon83 Oct 22, 2024
809db54
logs
Oct 22, 2024
f32d55f
hour ago
Oct 23, 2024
089073e
update next hour update logic
Oct 23, 2024
3cde00a
updated render time ago to state over an hour after 59 mins not 60
LeeGordon83 Oct 23, 2024
aeb22ec
remove console logs
Oct 23, 2024
2ef291a
merged dev in to resolve conflicts
LeeGordon83 Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions server/src/js/components/latest-levels-auto-refresh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/* global DOMParser */

class LatestLevelsAutoRefresh {
constructor (targetMinutes = [3, 18, 33, 48]) {
this.timeout = null
this.timeAgoInterval = null
this.liveStatusMessages = []
this.targetMinutes = targetMinutes

this.latestLevels = document.querySelectorAll('.defra-live__item')
}

updateLiveStatus = () => {
if (this.liveStatusMessages.length === 0) {
return
}

const element = document.querySelector('[data-live-status]')

if (!element) {
return
}

element.innerHTML = ''

const p = document.createElement('p')
p.innerText = this.liveStatusMessages.join('. ')
element.append(p)
}

updateTimeAgo = () => {
setTimeout(() => {
this.renderTimeAgo()
this.timeAgoInterval = setInterval(this.renderTimeAgo, 60000)
}, (60 - new Date().getSeconds()) * 1000)
}

renderTimeAgo = () => {
const elements = document.querySelectorAll('[data-item-time]')

elements.forEach(element => {
const timeAgoText = element.textContent
const timeAgoValue = parseInt(timeAgoText, 10)

if (!timeAgoText.includes('hour')) {
element.textContent = `${timeAgoValue + 1} minutes ago`
}

if ((timeAgoValue + 1) > 59) {
element.textContent = 'More than 1 hour ago'
}
})
}

fetchRiverLevels = (callback) => {
this.liveStatusMessages = []

fetch(window.location.href)
.then(res => {
if (!res.ok) {
throw new Error('Failed to fetch data')
}

return res.text()
})
.then(html => {
this.updateRiverLevels(html)

if (callback) {
callback()
}
})
.catch(error => {
console.error('Error updating levels:', error)

this.liveStatusMessages.push('There was an error getting the latest level')
})
.finally(() => {
this.updateLiveStatus()
})
}

updateRiverLevels = (html) => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')

const currentStatus = document.querySelector('[data-severity-status]')?.getAttribute('data-severity-status')
const newStatus = doc.querySelector('[data-severity-status]')?.getAttribute('data-severity-status')

if (currentStatus !== newStatus) {
return window.location.reload()
}

// Get elements from fetched content
const fetchedElements = Array.from(doc.querySelectorAll('.defra-live .defra-live__item'))

// Check if any elements are missing in the fetched data
const isMissingElements = this.latestLevels.length !== fetchedElements.length

if (isMissingElements) {
return this.liveStatusMessages.push('Warnings have been removed, please refresh the page.')
}

fetchedElements.forEach((fetchedElement) => {
const itemId = fetchedElement.getAttribute('data-item-id')
const itemRiverName = fetchedElement.getAttribute('data-item-name')
const itemRiverAgency = fetchedElement.getAttribute('data-item-agency')

const fetchedTime = fetchedElement.querySelector('[data-item-time]')
const fetchedValue = fetchedElement.querySelector('[data-item-value]')
const fetchedStatus = fetchedElement.getAttribute('data-item-status')

const currentItem = document.querySelector(`[data-item-id="${itemId}"]`)

if (currentItem) {
const currentTime = currentItem.querySelector('[data-item-time]')
const currentValue = currentItem.querySelector('[data-item-value]')
const currentStatus = currentItem.getAttribute('data-item-status')

if (fetchedStatus === currentStatus) {
if (fetchedValue?.textContent !== currentValue?.textContent) {
clearInterval(this.timeAgoInterval)

currentValue.textContent = fetchedValue.textContent

this.liveStatusMessages.push(`The ${itemRiverName} at ${itemRiverAgency} level was ${fetchedValue.textContent} metres ${fetchedTime.textContent}`)

this.updateTimeAgo()
}

currentTime.textContent = fetchedTime.textContent
} else {
this.liveStatusMessages.push('Please refresh the page')
}
} else {
this.liveStatusMessages.push('Please refresh the page')
}
})
}

nextUpdate = () => {
clearTimeout(this.timeout)

const now = new Date()
const nowMinute = now.getMinutes()

const nextTargetMinute = this.targetMinutes.find(minute => minute > nowMinute) ?? this.targetMinutes[0]

// Create the next target date based on the next target minute
const nextTargetDate = new Date(now)
nextTargetDate.setMinutes(nextTargetMinute)
nextTargetDate.setSeconds(0)
nextTargetDate.setMilliseconds(0)

if (nowMinute > this.targetMinutes[this.targetMinutes.length - 1]) {
nextTargetDate.setHours(nextTargetDate.getHours() + 1)
}

const delay = nextTargetDate.getTime() - now.getTime()

// Schedule the next update
this.timeout = setTimeout(() => {
this.fetchRiverLevels()
this.nextUpdate()
}, delay)
}
}

window.LatestLevelsAutoRefresh = LatestLevelsAutoRefresh
2 changes: 1 addition & 1 deletion server/src/sass/objects/_buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@
margin-bottom: -4px;
top: 0px;
}
}
}
27 changes: 22 additions & 5 deletions server/views/partials/latest-levels.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
<output class="govuk-visually-hidden" data-live-status></output>

<div class="defra-live">
<h2 class="defra-live__title">Latest level{% if model.latestLevels.length > 1 %}s{% endif %}</h2>
{% for warnings in model.latestLevels %}
<div class="defra-live__item">
{% if warnings.isSuspendedOrOffline %}
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0"><strong>{{ warnings.formatted_time }}</strong></p>
<div class="defra-live__item" data-item-status="{{ warnings.status }}" data-item-name="{{ warnings.river_name }}" data-item-agency="{{ warnings.agency_name }}" data-item-id="{{ warnings.rloi_id }}{% if warnings.direction == 'd' %}-downstage{% endif %}">
{% if warnings.status == 'Suspended' or (warnings.status == 'Active' and warnings.latest_level == null) %}
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0">
<strong>Latest Level</strong>
</p>
<p>The {{ warnings.river_name }} level at {{ warnings.agency_name }} is currently unavailable.</p>
{% else %}
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0"><strong>{{ warnings.formatted_time }}</strong></p>
<p>The {{ warnings.river_name }} level at {{ warnings.agency_name }} was {{ warnings.latest_level | toFixed(2) }} metres. Property flooding is possible when it goes above {{ warnings.threshold_value | toFixed(2) }} metres.
<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0">
<strong data-item-time>{{ warnings.formatted_time }}</strong>
</p>
<p>The {{ warnings.river_name }} level at {{ warnings.agency_name }} was <span data-item-value>{{ warnings.latest_level | toFixed(2) }}</span> metres. Property flooding is possible when it goes above {{ warnings.threshold_value | toFixed(2) }} metres.
{% if model.latestLevels.length > 1 %}
<a href="/station/{{ warnings.rloi_id }}{% if warnings.direction == 'd' %}-downstage{% endif %}{% if not warnings.iswales %}?tid={{ warnings.station_threshold_id }}{% endif %}">Monitor the {{ warnings.river_name }} level at {{ warnings.agency_name }}{% if warnings.iswales %} (Natural Resources Wales){% endif %}.</a>
{% endif %}
Expand All @@ -22,3 +28,14 @@ <h2 class="defra-live__title">Latest level{% if model.latestLevels.length > 1 %}
{% endfor %}
<p class="defra-live__supplementary">{% if model.latestLevels.length > 1 %}These levels{% else %}This level{% endif %} will update automatically</p>
</div>



<script src="{{ assetPath }}/js/latest-levels-auto-refresh.js"></script>
<script>
(function () {
const autorefresh = new window.LatestLevelsAutoRefresh()
autorefresh.updateTimeAgo()
autorefresh.nextUpdate()
})()
</script>
2 changes: 1 addition & 1 deletion server/views/target-area.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<!-- FIRST BANNER FOR ACTIVE ALERTS/WARNING -->
<div class="defra-flood-status govuk-!-margin-bottom-3">
{% if model.flood and model.severity.id < 4 %}
<div class="defra-flood-status-item defra-flood-status-item--{{model.severity.hash}}">
<div class="defra-flood-status-item defra-flood-status-item--{{model.severity.hash}}" data-severity-status="{{model.severity.hash}}">
<span class="defra-flood-status-item__icon">
{{model.severity.icon | safe }}
</span>
Expand Down
25 changes: 11 additions & 14 deletions test/routes/target-area.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ lab.experiment('Target-area tests', () => {

// Latest level (single threshold)
Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest level</h2>')
Code.expect(response.payload).to.contain('<p>The River Derwent level at Derby St Marys was 0.54 metres. Property flooding is possible when it goes above 3.30 metres.')
Code.expect(response.payload).to.contain('The River Derwent level at Derby St Marys was <span data-item-value>0.54</span> metres. Property flooding is possible when it goes above 3.30 metres.')
Code.expect(response.payload).to.contain('<a href="/station/2138?tid=1746074">Monitor the latest level at Derby St Marys</a>')
Code.expect(response.payload).to.match(/<div class="defra-flood-status-item__text">\s*<strong>Flooding is possible - <a class="govuk-link" href="https:\/\/www\.gov\.uk\/guidance\/flood-alerts-and-warnings-what-they-are-and-what-to-do#flood-alert">\s*be prepared\s*<\/a><\/strong>\s*<\/div>/)
Code.expect(response.payload).to.contain('<p class="defra-flood-meta defra-flood-meta--no-border govuk-!-margin-bottom-0"><strong>30 minutes ago</strong></p>')
Code.expect(response.payload).to.contain('30 minutes ago')

clock.restore()
})
Expand Down Expand Up @@ -191,12 +191,11 @@ lab.experiment('Target-area tests', () => {
// latests levels (multi)
// console.log('DEFRA Live Elements:', response.payload.match(/<div class="defra-live[^>]*>[\s\S]*?<\/div>/g)) // Keep for debugging
Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road was 0.18 metres. Property flooding is possible when it goes above 1.46 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road was <span data-item-value>0.18</span> metres. Property flooding is possible when it goes above 1.46 metres.')
Code.expect(response.payload).to.contain('<a href="/station/7173?tid=1747543">Monitor the River Pinn level at Avenue Road.</a>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Moss Close was 0.13 metres. Property flooding is possible when it goes above 1.15 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Moss Close was <span data-item-value>0.13</span> metres. Property flooding is possible when it goes above 1.15 metres.')
Code.expect(response.payload).to.contain('<a href="/station/7201?tid=1747541">Monitor the River Pinn level at Moss Close.</a>')
Code.expect(response.payload).to.contain('<p class="defra-live__supplementary">These levels will update automatically</p>')
})
lab.test('Check flood severity banner link for Flood warning', async () => {
const floodService = require('../../server/services/flood')
Expand Down Expand Up @@ -661,7 +660,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
})

Expand Down Expand Up @@ -710,7 +709,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
Code.expect(response.payload).to.contain('<p class="defra-live__supplementary">These levels will update automatically</p>')
})
Expand Down Expand Up @@ -760,7 +759,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest level</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p class="defra-live__supplementary">This level will update automatically</p>')
})

Expand Down Expand Up @@ -809,7 +808,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
Code.expect(response.payload).to.not.contain('<p>The River Welsh station level is currently unavailable.</p>')
Code.expect(response.payload).to.contain('<p class="defra-live__supplementary">These levels will update automatically</p>')
Expand Down Expand Up @@ -860,7 +859,7 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest levels</h2>')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Eastcote Road was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.')
Code.expect(response.payload).to.contain('<p>The River Pinn level at Avenue Road is currently unavailable.</p>')
Code.expect(response.payload).to.not.contain('<p>The River Test level at Test Road is currently unavailable.</p>')
Code.expect(response.payload).to.contain('<p class="defra-live__supplementary">These levels will update automatically</p>')
Expand Down Expand Up @@ -957,8 +956,6 @@ lab.experiment('Target-area tests', () => {
Code.expect(response.statusCode).to.equal(200)

Code.expect(response.payload).to.contain('<h2 class="defra-live__title">Latest level</h2>')
Code.expect(response.payload).to.contain('<p>The River Welsh level at Welsh Station was 0.35 metres. Property flooding is possible when it goes above 1.40 metres.\n \n </p>')
Code.expect(response.payload).to.contain('<a href="/station/7201">Monitor the latest level at Welsh Station (Natural Resources Wales)</a>')
Code.expect(response.payload).to.contain('<p class="defra-live__supplementary">This level will update automatically</p>')
Code.expect(response.payload).to.contain('<p>The River Welsh level at Welsh Station was <span data-item-value>0.35</span> metres. Property flooding is possible when it goes above 1.40 metres.\n \n </p>')
})
})
Loading
Loading