Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/pull-req.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
github.event_name == 'pull_request' && (
github.event.action == 'review_requested' ||
github.base_ref == 'master' ||
(github.base_ref == 'dev' && (
((github.base_ref == 'dev' || github.base_ref == 'dev-flex-2024') && (
github.event.pull_request.draft == false ||
startsWith(github.head_ref, 'dependabot/')
))
Expand Down
208 changes: 207 additions & 1 deletion __tests__/end-to-end.js
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,19 @@ async function getInnerHTMLFromSelector (selector: string) {
return stripReactTags(html)
}

/**
* Gets the id of a given selector.
*/
async function getIdFromSelector (selector: string) {
log.info(`getting id for selector: ${selector}`)
const id = (await page.$eval(selector, el => {
const _el = (el: any)
// make flow happy cause flow-typed page.$eval doesn't get specifc enough
return _el.id
}): any)
return id
}

/**
* Gets all the element handles found using the given selector.
*/
Expand Down Expand Up @@ -1070,7 +1083,7 @@ describe('end-to-end', () => {
await createProject(testProjectToDeleteName)

// go back to project list
await goto('http://localhost:9966/project', {waitUntil: 'networkidle0'})
await goto('https://datatools-ui-proxy/project', {waitUntil: 'networkidle0'})

// get the created project id
// go into the project page and verify that it looks ok-ish
Expand Down Expand Up @@ -1186,6 +1199,143 @@ describe('end-to-end', () => {
await expectFeedVersionValidityDates('Apr 8, 2018', 'Jun 30, 2018')
}, defaultTestTimeout)

makeTestPostFeedSource('should be able to download and validate snapshot gtfs', async () => {
// go to main feed tab
await waitForAndClick('#feed-source-viewer-tabs-tab-')
await wait(5000, 'additional time for page to load')

// wait for main tab to show up with version validity info
await waitForSelector('[data-test-id="active-feed-version-validity-start"]')

// click load version button
await click('[data-test-id="load-feed-version-button"]')
await waitForAndClick('[data-test-id="modal-confirm-ok-button"]')

// wait for load to finish
await waitAndClearCompletedJobs()

// wait for page to be visible and go to snapshots tab
await waitForAndClick('#feed-source-viewer-tabs-tab-snapshots')
await wait(2000, 'for page to load?')

// wait for snapshots tab to load and create snapshot
await waitForAndClick('[data-test-id="snapshot-latest-changes-button"]')

// wait for snapshot export modal and click "no" to proprietary file export
await waitForAndClick('[data-test-id="confirm-snapshot-create-button"]')

// wait for version to get created
await waitAndClearCompletedJobs()

// the page has to reload to show the new snapshot
// TODO: Fix?
await page.reload({ waitUntil: 'networkidle0' })

// Download version
await waitForAndClick('[data-test-id="download-snapshot-button"]')
await wait(15000, 'for file to download')

const fileName = await getIdFromSelector('[data-test-id="download-snapshot-button"]')
// file should get saved to the current root directory, go looking for it
// verify that file exists
const downloadsDir = './'
// $FlowFixMe old version of flow doesn't know latest fs methods
const files = await fs.readdir(downloadsDir)
log.info(fileName)
log.info(files)

let feedVersionDownloadFile = ''
// assume that this file will be the first zip file download
for (const file of files) {
if (file.indexOf(fileName.replace(/:/g, '')) > -1) {
feedVersionDownloadFile = file
break
}
}
if (!feedVersionDownloadFile) {
throw new Error('Feed Version gtfs file not found in Downloads folder!')
}

const filePath = path.join(downloadsDir, feedVersionDownloadFile)

// go to main feed tab
await waitForAndClick('#feed-source-viewer-tabs-tab-')
await wait(5000, 'additional time for page to load')

// wait for main tab to show up with version validity info
await waitForSelector('[data-test-id="active-feed-version-validity-start"]')

const origDtErrorCount = await getInnerHTMLFromSelector('[data-test-id="dt-error-count-label"]')
const origMdErrorCount = await getInnerHTMLFromSelector('[data-test-id="md-error-count-label"]')

// Open dropdown
await waitForAndClick(
'#bg-nested-dropdown',
{ visible: true }
)
// create new version by fetching
await waitForAndClick(
'[data-test-id="upload-feed-button"]',
{ visible: true }
)

// upload file to form
const fileUploadForm = await page.$('input[type=file]')
await fileUploadForm.uploadFile(filePath)

// click "OK to upload file
await waitForAndClick('[data-test-id="upload-gtfs-modal-ok"]')
// wait for version to get created
await waitAndClearCompletedJobs()

// delete file
// $FlowFixMe old version of flow doesn't know latest fs methods
await fs.remove(filePath)

// go to main feed tab
await click('#feed-source-viewer-tabs-tab-')

// wait for main tab to show up with version validity info
await waitForSelector('[data-test-id="active-feed-version-validity-start"]')

// verify that snapshot was made active version
await expectFeedVersionValidityDates('May 29, 2018', 'May 29, 2028')

// open validation results
await click('[data-test-id="validation-issues-link"]')
await waitForSelector('[data-test-id="dt-error-count-label"]')

const newDtErrorCount = await getInnerHTMLFromSelector('[data-test-id="dt-error-count-label"]')
const newMdErrorCount = await getInnerHTMLFromSelector('[data-test-id="md-error-count-label"]')

expect(newDtErrorCount).toEqual(origDtErrorCount)
expect(newMdErrorCount).toEqual(origMdErrorCount)

// todo: check rest of validation results for correct counts

// go to main feed tab
await click('#feed-source-viewer-tabs-tab-')

// wait for main tab to show up with version validity info
await waitForSelector('[data-test-id="active-feed-version-validity-start"]')

// remove version and snapshot
await waitForAndClick('[data-test-id="delete-feed-version-button"]')
// confirm action in modal
await waitForAndClick('[data-test-id="modal-confirm-ok-button"]')
await wait(2000, 'for data to refresh')
await waitForSelector('#feed-source-viewer-tabs')

// wait for page to be visible and go to snapshots tab
await waitForAndClick('#feed-source-viewer-tabs-tab-snapshots')
await wait(2000, 'for page to load?')

// wait for snapshots tab to load and delete snapshot
await waitForAndClick('[data-test-id="delete-snapshot-button"]')
await waitForAndClick('[data-test-id="modal-confirm-ok-button"]')
await wait(2000, 'for page to load?')
}, defaultTestTimeout)

if (doNonEssentialSteps) {
makeTestPostFeedSource('should delete feed source', async () => {
const testFeedSourceToDeleteName = `test-feed-source-to-delete-${testTime}`
Expand Down Expand Up @@ -2684,6 +2834,62 @@ describe('end-to-end', () => {
)
}, defaultTestTimeout, 'should create trip')

makeEditorEntityTest('should create trip data via series editor', async () => {
// open series editor
await click('[data-test-id="create-trip-series-button"]')

// wait for modal to appear
await waitForSelector(
'#hours'
)

// click hours field
await click('#hours:nth-child(1)')

// enter hours
await page.keyboard.type('13')

// tab to headway
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')

// enter minutes
await page.keyboard.type('5')

// tab to end time
await page.keyboard.press('Tab')

// enter hours
await page.keyboard.type('15')

// submit
await click('[data-test-id="generate-trips-button"]')

// wait for save to happen
await wait(2000, 'for save to happen')

// save
await click('[data-test-id="save-trip-button"]')

// wait for save to happen
await wait(2000, 'for save to happen')

// reload to make sure stuff was saved
await page.reload({ waitUntil: 'networkidle0' })

// wait for timetable to appear
await waitForSelector(
'[data-test-id="timetable-area"]'
)

// verify data was generated correctly and retrieved from server
await expectSelectorToContainHtml(
'[data-test-id="timetable-area"]',
'13:05:00'
)
}, defaultTestTimeout, 'should create trip')

makeEditorEntityTest('should delete trip data', async () => {
// create a new trip that will get deleted
await click('[data-test-id="duplicate-trip-button"]')
Expand Down
3 changes: 3 additions & 0 deletions docs/user/otp-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ The deployment architecture diagram below depicts how OTP servers are managed by
1. [Setting up OTP UI and backend servers on AWS](./setting-up-aws-servers.md)
2. [Adding a deployment server from TRANSIT-data-tools](./add-deployment-server.md)
3. [Deploying GTFS feeds to OTP](./deploying-feeds.md)

#### Warning:
Datatools uses the [OTP Actuator API](https://docs.opentripplanner.org/en/latest/sandbox/ActuatorAPI) to determine if OTP started correctly. If you do not enable this API, the deployment will not succeed.
2 changes: 1 addition & 1 deletion lib/common/components/SelectFileModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export default class SelectFileModal extends Component<Props, State> {
</Body>

<Footer>
<Button disabled={disabled} onClick={this.ok}>{this.messages('ok')}</Button>
<Button disabled={disabled} onClick={this.ok} data-test-id='upload-gtfs-modal-ok'>{this.messages('ok')}</Button>
<Button disabled={disabled} onClick={this.close}>{this.messages('cancel')}</Button>
</Footer>
</Modal>
Expand Down
4 changes: 4 additions & 0 deletions lib/editor/components/EditorFeedSourcePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export default class EditorFeedSourcePanel extends Component<Props> {
<Button
block
bsStyle='primary'
data-test-id='snapshot-latest-changes-button'
disabled={editDisabled}
onClick={this._openModal}
style={{marginBottom: '20px'}}>
Expand Down Expand Up @@ -204,6 +205,8 @@ class SnapshotItem extends Component<ItemProps> {
{/* Download button */}
<Button
bsSize='small'
data-test-id='download-snapshot-button'
id={snapshot.id}
onClick={this._onClickDownload}>
<Glyphicon glyph='download' />{' '}
{this.messages('download')}
Expand All @@ -223,6 +226,7 @@ class SnapshotItem extends Component<ItemProps> {
{/* Delete button */}
<Button
bsSize='small'
data-test-id='delete-snapshot-button'
disabled={disabled}
onClick={this._onDeleteSnapshot}>
<span className='text-danger'>
Expand Down
1 change: 1 addition & 0 deletions lib/editor/components/timetable/TripSeriesModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ const TripSeriesModal = (props: Props) => {
<Footer>
<Button
bsStyle='primary'
data-test-id='generate-trips-button'
disabled={generateTripsDisabled}
onClick={onClickGenerate}
title={generateTripsDisabled && messages('disabledTooltip')}
Expand Down
6 changes: 3 additions & 3 deletions lib/manager/components/version/FeedVersionViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,10 @@ class VersionSectionSelector extends Component<SelectorProps> {

return (
<div style={{ display: 'inline' }}>
<BsLabel className={`gtfs-error-${highestPriority}-label-solid`}>
<BsLabel className={`gtfs-error-${highestPriority}-label-solid`} data-test-id='dt-error-count-label'>
DT {dtValidationCount}
</BsLabel>
{mbValidationCount && <BsLabel style={{marginLeft: '1ch'}} className={`gtfs-error-${highestMBPriority}-label-solid`}>
{mbValidationCount && <BsLabel style={{marginLeft: '1ch'}} className={`gtfs-error-${highestMBPriority}-label-solid`} data-test-id='md-error-count-label'>
MD {mbValidationCount}
</BsLabel> }
{diffLabel}
Expand Down Expand Up @@ -277,7 +277,7 @@ class VersionSectionSelector extends Component<SelectorProps> {
active={versionSection === 'issues'}
to={`${versionPath}/issues`}
>
<ListGroupItem>
<ListGroupItem data-test-id='validation-issues-link'>
<Icon type='exclamation-triangle' /> Validation issues {this._renderIssuesLabel()}
</ListGroupItem>
</LinkContainer>
Expand Down
1 change: 1 addition & 0 deletions lib/manager/components/version/VersionButtonToolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export default class VersionButtonToolbar extends Component<ToolbarProps> {
{isModuleEnabled('editor') && !isPublic
? <Button
bsSize={size}
data-test-id='load-feed-version-button'
disabled={editDisabled || !hasVersions}
onClick={this._onClickLoadIntoEditor}>
<Glyphicon glyph='pencil' />
Expand Down
Loading