Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</div>

<div class="d-flex justify-content-end gap-2">
<button type="submit" class="btn btn-sm btn-primary">
<button type="submit" class="btn btn-sm btn-primary" data-test-id="select-collection-submit">
<i class="bi bi-save-fill me-1"></i> <%= t('connectors.dataverse.collection_select_form.submit') %>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@


<div class="d-flex justify-content-end gap-2">
<button type="submit" class="btn btn-sm btn-primary">
<button type="submit" class="btn btn-sm btn-primary" data-test-id="select-dataset-submit">
<i class="bi bi-save-fill me-1"></i> <%= t('connectors.dataverse.dataset_select_form.submit') %>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<% if upload_bundle.connector_metadata.select_collection? %>
<button type="button"
class="btn btn-outline-primary btn-badge me-2"
data-test-id="select-collection-btn"
title="<%= t('connectors.dataverse.upload_bundle_actions_bar.button_select_collection_title') %>"
data-controller="modal"
data-action="click->modal#load"
Expand All @@ -62,6 +63,7 @@
<% if upload_bundle.connector_metadata.select_dataset? %>
<button type="button"
class="btn btn-outline-primary btn-badge me-2"
data-test-id="select-dataset-btn"
title="<%= t('connectors.dataverse.upload_bundle_actions_bar.button_dataset_form_tabs_title') %>"
data-controller="modal"
data-action="click->modal#load"
Expand Down Expand Up @@ -91,6 +93,7 @@

<button type="button"
class="btn btn-sm btn-outline-primary"
data-test-id="edit-api-key-btn"
title="<%= t(".button_edit_key_title") %>"
data-controller="modal"
data-action="click->modal#load"
Expand Down
3 changes: 3 additions & 0 deletions application/app/views/file_browser/_browser.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<!-- Actions (right) -->
<div>
<button class="btn btn-sm btn-outline-dark" type="button"
data-test-id="fb-edit-path-btn"
title="<%= t('.button_edit_path_title') %>"
aria-label="<%= t('.button_edit_path_label') %>"
data-action="click->file-browser#editPath">
Expand All @@ -67,6 +68,7 @@
</button>

<button class="btn btn-sm btn-outline-dark" type="button"
data-test-id="fb-home-btn"
data-entry-path="<%= Dir.home %>"
data-entry-type="folder"
title="<%= t('.button_home_title') %>"
Expand All @@ -79,6 +81,7 @@
<%= render partial: '/shared/ood_folder_button', locals: { path: current_path }%>

<button class="btn btn-sm btn-outline-dark" type="button"
data-test-id="fb-close-btn"
title="<%= t('.button_close_browser_title') %>"
aria-label="<%= t('.button_close_browser_label') %>"
data-action="click->file-browser#hideContainer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
'modal-id-value': 'global-modal',
'download-file-id': file.id
} do %>
<%= status_badge(file.status, title: file.end_date, filename: file.filename) %>
<%= status_badge(file.status, filename: file.filename) %>
<span class="visually-hidden"><%= t('.button_view_events_label') %></span>
<% end %>
<% if file.status.success? %>
Expand Down
2 changes: 1 addition & 1 deletion application/app/views/projects/show/_upload_files.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
'modal-id-value': 'global-modal',
'upload-file-id': file.id
} do %>
<%= status_badge(file.status, title: file.end_date, filename: file.filename) %>
<%= status_badge(file.status, filename: file.filename) %>
<span class="visually-hidden"><%= t('.button_view_events_label') %></span>
<% end %>
<% if file.status.success? %>
Expand Down
2 changes: 1 addition & 1 deletion application/app/views/upload_status/_files.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<%= render partial: '/shared/files_process_header', locals: { type: 'upload' } %>
</div>
<div class="card-body bg-light px-0">
<div class="container files" role="table">
<div class="container files" data-test-id="uploads-list" role="table">
<% files.each_with_index do |data, index| %>
<div class="row py-2 align-items-center <%= 'custom-stripe' if index.even? %>" role="row">
<div class="col-md-10" role="cell">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'aria-label': t('projects.show.project_actions.button_create_upload_bundle_placeholder') %>
<%= button_tag type: 'submit',
class: 'btn btn-outline-primary',
data: {test_id: 'create-bundle-from-url-submit'},
title: t('projects.show.project_actions.button_create_upload_bundle_title') do %>
<i class="bi bi-folder-plus" aria-hidden="true"></i>
<span class="visually-hidden"><%= t('projects.show.project_actions.button_create_upload_bundle_label') %></span>
Expand Down
1 change: 1 addition & 0 deletions e2e_tests/config/upload_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uORt06F7LEheAIbZCUmoPXp7ztqcUlBWcpf6qqaf6L7x8/HAa1RlbVJmB4oZmOwBiagyE+VoTxu1p6TEy+A5OJDUD2iKUNemGRUFNHuEQO9hZTX8JB4EBaFkdTpFRQF9do9Z/rTewzBGtlVWpfEaaAdZuhmmgS7T78XZ60JaEE6AndSpD+ocqdenFjopDaT0g/gU0tHNweE6KCoDnsDneK9vdnBqJ2HlHSMjLkB4eU6dj6u10nT6mpdx5lVzEvqpc14WiMbp7fdKQfwKBQ5NNnGiceDOseUvhqrUfpx+MZbhu39tXpfJ4oMBWw/FRJJrshfDCVaX241Gw4jJPJVPNBRHpzJSy8R2jjkUW3NrA7WOjhBYw9Ga1tVln+rgmnHwnayOl6Nh6oeEzVFOAb7/iODtrGLdiz9A70viGRV35JEc7E6ZPn+DBYAfwtSsd38p5rclfN236QAG62j4X9r9IhemEcoR07tGSEqy+1Dq6HN5d474vRAz4sqfQX8KKtaRPSywqnm8pgWkfeBCYHXdBW7vm79xOSQKpVB9KxuPk5zGP46e1bIBJgjq6VEUTAbEf6f+X7WbCSaQ9hPeadADF7J4ZYccPoo2gwmtmZNvx6dRNgkqQpR6hF1TvYc91V3ohr5U5YdEHsr+G7YidEbr2C5jW1wN6HVaE0S9cJbVaVHuCX7D8zHLRPtJE62w3m6XP7shghWc1MZVv6G22ikw8vHL2VpUqtOwGbfhAGJEADeQDvIYWlR9LOc1D10On8MAGWIXb/zskZDUy21uljEt2B+hWki345yCohIpvFqbc4+Ko6/QFNkz5TudZDobfKhZXUrOoeX2zbefwV3xdhqPIihWElK2NDVxxb+wUQ02HHdh9SdrgHIXsxsCADUTtK0VAiW577NK4dc15buXCDmeHNh7BYU3JGahZ9T5yoERg/TLNUYYbzTg7xmEUdNP4hvPMGcZJ8ojxJkvk2iC+MiwiZoYsX/c4EyRXduxmorN97bl+3Sc3p3Ck/s2m01u6ptqMXl9HoqOIuN/zQwN2yoNBVCYBRYMudjw7r4nK28fzPxhTYv2+/laOruBnj1nGJwtUun8Rz1lYIR6gn8NuRgJvrKBAsr3pKhSEYdgr2Y7pOxbWSjRr/5xYloPpCWd2FLw1vpeb+4Lbu8/IbLDjP5jdXcpKh4rxD57ys176fsDe7f/rGSuoiWbcOgoxUJ1PhmvzROqiKUbBrRtoTHt4POiRyqGkk9F/m64tA8xTJzMuri9e0ubv0kpEhelCnlXY4Uieo+HKxWIUq9jzg8DKRuK5XxExq9I9CT9pXOUawXaK16krpCdToyVfb3Ltxr3AOJYEAmqSOW+OeaXcXLw381FwA==
4 changes: 2 additions & 2 deletions e2e_tests/cypress/e2e/browse/explore_widget_dataverse.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('Explore Widget - Dataverse', () => {

// Verify pagination is present
cy.get('nav[aria-label="Search result pagination"]').should('be.visible')
cy.get('.card-header').contains('11 to 30 of 195882 results').should('be.visible')
cy.get('.card-header').contains('11 to 30 of 188518 results').should('be.visible')
cy.get('a[aria-label="Go to next page"]').should('be.visible')
cy.get('a[title="Next page"]').should('be.visible')

Expand Down Expand Up @@ -116,7 +116,7 @@ describe('Explore Widget - Dataverse', () => {
appActionsBar.exploreRepository(dataverse.DATAVERSE_URL)

// Verify we're on page 1
cy.get('.card-header').contains('11 to 30 of 195882 results').should('be.visible')
cy.get('.card-header').contains('11 to 30 of 188518 results').should('be.visible')

// Click next page
cy.get('a[data-test-id="header-pagination-next"]').click()
Expand Down
10 changes: 0 additions & 10 deletions e2e_tests/cypress/e2e/workflows/download_file_workflow.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,11 @@ import flashMessageComponent from '../../pages/FlashMessageComponent'

describe('Workflow: Download Files from Dataverse', () => {
const PROJECT_NAME = 'DownloadFileWorkflow'
let projectId

beforeEach(() => {
homePage.visitLoopRoot()
})

after(() => {
// Cleanup: Delete the project after the test
if (projectId) {
projectIndexPage.visit()
projectIndexPage.deleteProject(projectId)
cy.task('log', `Cleaned up project: ${projectId}`)
}
})

it('should complete full workflow: create project, download files from dataverse, and verify downloads', () => {
cy.task('log', 'Starting download file workflow test')
cy.task('log', 'Step 0: Cleanup')
Expand Down
179 changes: 179 additions & 0 deletions e2e_tests/cypress/e2e/workflows/upload_file_workflow.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import homePage from '../../pages/HomePage'
import projectIndexPage from '../../pages/ProjectIndexPage'
import projectDetailsPage from '../../pages/ProjectDetailsPage'
import uploadsPage from '../../pages/UploadsPage'
import dataverse from '../../pages/connectors/Dataverse'
import flashMessageComponent from '../../pages/FlashMessageComponent'
import fileBrowserComponent from '../../pages/FileBrowserComponent'

describe('Workflow: Upload Files to Dataverse', () => {
const PROJECT_NAME = 'UploadFileWorkflow'
const API_KEY = 'test-api-key-12345'
const UPLOAD_FILE = 'upload_file.txt'

beforeEach(() => {
homePage.visitLoopRoot()
})

it('should complete full workflow: create project, upload files to dataverse, and verify uploads', () => {
cy.task('log', 'Starting upload file workflow test')
cy.task('log', 'Step 0: Cleanup')
projectIndexPage.deleteProjects()

// Step 1: Create a new project
cy.task('log', 'Step 1: Creating new project')
projectIndexPage.visit()
projectIndexPage.getPageContainer().should('be.visible')
projectIndexPage.clickCreateProject()

// Verify project creation
flashMessageComponent.getFlashAlert().should('contain', 'created')
projectDetailsPage.assertInProjectDetails()

cy.get('[data-project-id]').invoke('attr', 'data-project-id').as('projectId')
cy.get('@projectId').then(projectId => {
cy.task('log', `Created project with ID: ${projectId}`)
})

// Step 2: Edit project name to "UploadFileWorkflow"
cy.task('log', 'Step 2: Editing project name')
projectDetailsPage.waitClickEditProjectName()
projectDetailsPage.typeProjectName(PROJECT_NAME)
projectDetailsPage.clickSaveName()

// Verify the name has been updated
projectDetailsPage.getProjectName().should('contain', PROJECT_NAME)
cy.task('log', `Project renamed to: ${PROJECT_NAME}`)

// Step 3: Create upload bundle using Dataverse URL
cy.task('log', 'Step 3: Creating upload bundle with Dataverse URL')
projectDetailsPage.clickCreateUploadBundle()
projectDetailsPage.createUploadBundle(dataverse.DATAVERSE_URL)
cy.task('log', `Created upload bundle for: ${dataverse.DATAVERSE_URL}`)

// Wait for upload bundle to be created and get its ID
cy.wait(1000) // Brief wait for the bundle to be created
// Store project ID for cleanup
cy.get('[data-upload-bundle-id]').first().invoke('attr', 'data-upload-bundle-id').as('bundleId')
cy.get('@bundleId').then(bundleId => {
cy.task('log', `Created upload bundle with ID: ${bundleId}`)
})

// Step 4: Add API key
cy.task('log', 'Step 4: Adding API key')
dataverse.clickEditApiKey()
// Wait for modal to load
cy.get('#global-modal').should('be.visible')

dataverse.enterApiKey(API_KEY)
dataverse.saveApiKey()
cy.task('log', 'API key added successfully')

// Wait for modal to close
cy.wait(1000)

// Step 5: Select a collection
cy.task('log', 'Step 5: Selecting collection')
dataverse.clickSelectCollection()

// Wait for modal to load with collections
dataverse.getModal().should('be.visible')
dataverse.getSelectCollectionItems().should('exist')

dataverse.selectFirstCollection()
dataverse.submitSelectCollectionForm()
cy.task('log', 'Selected first collection from list')

// Wait for modal to close
cy.wait(1000)

// Step 6: Select a dataset
cy.task('log', 'Step 6: Selecting dataset')
dataverse.clickSelectDataset()

// Wait for modal to load with datasets
dataverse.getModal().should('be.visible')
dataverse.getSelectDatasetItems().should('exist')

dataverse.selectFirstDataset()
dataverse.submitSelectDatasetForm()
cy.task('log', 'Selected first dataset from list')

// Step 7: Click add files to open file browser
cy.task('log', 'Step 7: Opening file browser to select upload file')
cy.get('@bundleId').then(bundleId => {
projectDetailsPage.clickUploadBundleAddFiles(bundleId)
return projectDetailsPage.getUploadBundleFileBrowser(bundleId).find('nav').should('exist')
})
cy.task('log', 'File browser opened')



// Step 8: Navigate to /home/ood using home icon
cy.task('log', 'Step 8: Navigating to /home/ood directory')
fileBrowserComponent.clickFileBrowserHome()
// Wait for navigation
cy.wait(500)

// Step 9: Select upload_file.txt by double click
cy.task('log', 'Step 9: Selecting upload_file.txt')
fileBrowserComponent.selectFileByDoubleClick(UPLOAD_FILE)
cy.wait(1000)
cy.task('log', `Selected file: ${UPLOAD_FILE}`)
// Step 10: Close file browser
cy.task('log', 'Step 10: Closing file browser')
fileBrowserComponent.closeFileBrowser()

// Step 11: Assert file is in the upload bundle list
cy.task('log', 'Step 11: Verifying file is in upload bundle')
cy.get('@bundleId').then(bundleId => {
projectDetailsPage.getUploadBundleFilesList(bundleId).should('be.visible')
projectDetailsPage.getUploadFileRows(bundleId).should('have.length', 1)
projectDetailsPage.getUploadFileRows(bundleId).first().invoke('attr', 'data-upload-file-id').as('fileId')
return projectDetailsPage.getUploadFileRows(bundleId).should('contain', UPLOAD_FILE)
})
cy.task('log', 'File appears in upload bundle file list')

// Step 12: Navigate to Uploads page and verify file with success status
cy.task('log', 'Step 12: Navigating to Uploads page')
uploadsPage.visit()

// Verify we're on the uploads page
uploadsPage.assertInUploads()

uploadsPage.getUploadsList().should('be.visible')
uploadsPage.getUploadFileRows().should('have.length.at.least', 1)
uploadsPage.getUploadFileRows().should('contain', UPLOAD_FILE)
uploadsPage.assertAllUploadFilesWithStatus('success')
cy.task('log', 'Verified file in Uploads page with success status')

// Step 13: Navigate to project details and verify in upload bundle tab
cy.task('log', 'Step 13: Verifying file in project upload bundle tab')

// Navigate to project index, then to the specific project
cy.get('@projectId').then(projectId => {
cy.task('log', `Navigate to project details`)
projectIndexPage.visit()
projectIndexPage.getProjectSummaryById(projectId).should('exist')
return projectIndexPage.getProjectNameLink(projectId).click()
})

// Verify we're back on the project details page
projectDetailsPage.assertInProjectDetails()

cy.get('@bundleId').then(bundleId => {
// Click on the upload bundle tab
projectDetailsPage.clickUploadBundleTab(bundleId)
cy.task('log', 'Clicked upload bundle tab')
// Verify file is shown in the upload bundle with success status
projectDetailsPage.getUploadBundleFilesList(bundleId).should('be.visible')
projectDetailsPage.getUploadFileRows(bundleId).should('have.length', 1)
cy.get('@fileId').then(fileId => {
projectDetailsPage.getUploadFileRowById(bundleId, fileId).should('contain', UPLOAD_FILE)
projectDetailsPage.getUploadFileRowById(bundleId, fileId).should('contain', 'success')
})
})
cy.task('log', 'Verified file in upload bundle tab with success status')
cy.task('log', 'Workflow completed successfully!')
})
})
2 changes: 1 addition & 1 deletion e2e_tests/cypress/pages/DownloadsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class DownloadsPage {
// PAGE REFRESHES EVERY 5s
// THIS IS A TRICK TO FORCE CYPRESS TO GET THE getDownloadFileRows ON EVERY RETRY
this.getDownloadFileRows()
.find('span.badge.file-status')
.find('span.badge.file-status', { timeout: 20000 })
.should($badges => {
expect($badges.length).to.be.greaterThan(0)
$badges.each((_, el) => {
Expand Down
23 changes: 23 additions & 0 deletions e2e_tests/cypress/pages/FileBrowserComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const selectors = {
fileBrowserHomeButton: '[data-test-id="fb-home-btn"]',
fileBrowserCloseButton: '[data-test-id="fb-close-btn"]',
// THIS USE REGULAR EXPRESSIONS TO MATCH THE FILE FULL PATH WITH JUST THE FILENAME
fileBrowserFileRow: (filename) => `li[data-entry-path*="${filename}"]`,
};

export class FileBrowserComponent {

clickFileBrowserHome() {
cy.get(selectors.fileBrowserHomeButton).click();
}

selectFileByDoubleClick(filename) {
cy.get(selectors.fileBrowserFileRow(filename)).dblclick();
}

closeFileBrowser() {
cy.get(selectors.fileBrowserCloseButton).click();
}
}

export default new FileBrowserComponent();
Loading