diff --git a/src/lib/project-fetcher-hoc.jsx b/src/lib/project-fetcher-hoc.jsx index 1879d69e582468e3af8ffa5377f7a80c1e5e544a..9f82fb3d7b878a9f9c430ccf67b5f0d080148a92 100644 --- a/src/lib/project-fetcher-hoc.jsx +++ b/src/lib/project-fetcher-hoc.jsx @@ -8,12 +8,18 @@ import {setProjectUnchanged} from '../reducers/project-changed'; import { LoadingStates, defaultProjectId, + getIsCreatingNew, getIsFetchingWithId, + getIsLoading, getIsShowingProject, onFetchedProjectData, projectError, setProjectId } from '../reducers/project-state'; +import { + activateTab, + BLOCKS_TAB_INDEX +} from '../reducers/editor-tab'; import analytics from './analytics'; import log from './log'; @@ -59,6 +65,9 @@ const ProjectFetcherHOC = function (WrappedComponent) { if (this.props.isShowingProject && !prevProps.isShowingProject) { this.props.onProjectLoaded(); } + if (this.props.isShowingProject && (prevProps.isLoadingProject || prevProps.isCreatingNew)) { + this.props.onActivateTab(BLOCKS_TAB_INDEX); + } } fetchProject (projectId, loadingState) { return storage @@ -89,7 +98,9 @@ const ProjectFetcherHOC = function (WrappedComponent) { /* eslint-disable no-unused-vars */ assetHost, intl, + isLoadingProject: isLoadingProjectProp, loadingState, + onActivateTab, onError: onErrorProp, onFetchedProjectData: onFetchedProjectDataProp, projectHost, @@ -113,7 +124,9 @@ const ProjectFetcherHOC = function (WrappedComponent) { canSave: PropTypes.bool, intl: intlShape.isRequired, isFetchingWithId: PropTypes.bool, + isLoadingProject: PropTypes.bool, loadingState: PropTypes.oneOf(LoadingStates), + onActivateTab: PropTypes.func, onError: PropTypes.func, onFetchedProjectData: PropTypes.func, projectHost: PropTypes.string, @@ -127,12 +140,15 @@ const ProjectFetcherHOC = function (WrappedComponent) { }; const mapStateToProps = state => ({ + isCreatingNew: getIsCreatingNew(state.scratchGui.projectState.loadingState), isFetchingWithId: getIsFetchingWithId(state.scratchGui.projectState.loadingState), + isLoadingProject: getIsLoading(state.scratchGui.projectState.loadingState), isShowingProject: getIsShowingProject(state.scratchGui.projectState.loadingState), loadingState: state.scratchGui.projectState.loadingState, reduxProjectId: state.scratchGui.projectState.projectId }); const mapDispatchToProps = dispatch => ({ + onActivateTab: tab => dispatch(activateTab(tab)), onError: error => dispatch(projectError(error)), onFetchedProjectData: (projectData, loadingState) => dispatch(onFetchedProjectData(projectData, loadingState)), diff --git a/src/reducers/project-state.js b/src/reducers/project-state.js index edec52a537c0f9fde8d9cbb07fbeffb281038227..a587844243a80dbac98e152b18989c614c6056c8 100644 --- a/src/reducers/project-state.js +++ b/src/reducers/project-state.js @@ -58,6 +58,11 @@ const getIsLoadingWithId = loadingState => ( loadingState === LoadingState.LOADING_VM_WITH_ID || loadingState === LoadingState.LOADING_VM_NEW_DEFAULT ); +const getIsLoading = loadingState => ( + loadingState === LoadingState.LOADING_VM_FILE_UPLOAD || + loadingState === LoadingState.LOADING_VM_WITH_ID || + loadingState === LoadingState.LOADING_VM_NEW_DEFAULT +); const getIsCreatingNew = loadingState => ( loadingState === LoadingState.CREATING_NEW ); @@ -488,6 +493,7 @@ export { getIsError, getIsFetchingWithId, getIsFetchingWithoutId, + getIsLoading, getIsLoadingWithId, getIsManualUpdating, getIsRemixing, diff --git a/test/integration/project-loading.test.js b/test/integration/project-loading.test.js index 09023632e8a1ac61b8c1598d7c3824c1e9a7ebed..687e11b1314ed01b8ba5039f9da4cc0b41c41098 100644 --- a/test/integration/project-loading.test.js +++ b/test/integration/project-loading.test.js @@ -7,7 +7,8 @@ const { findByXpath, getDriver, getLogs, - loadUri + loadUri, + scope } = new SeleniumHelper(); const uri = path.resolve(__dirname, '../../build/index.html'); @@ -105,5 +106,27 @@ describe('Loading scratch gui', () => { const logs = await getLogs(); await expect(logs).toEqual([]); }); + + test('Creating new project resets active tab to Code tab', async () => { + await loadUri(uri); + await clickText('View 2.0 Project'); + const el = await findByXpath("//input[@placeholder='scratch.mit.edu/projects/123456789']"); + const projectId = '96708228'; + await el.sendKeys(`scratch.mit.edu/projects/${projectId}`); + await clickXpath('//button[@title="View Project"]'); + await new Promise(resolve => setTimeout(resolve, 2000)); + await findByXpath('//*[span[text()="Costumes"]]'); + await clickText('Costumes'); + await clickXpath( + '//div[contains(@class, "menu-bar_menu-bar-item") and ' + + 'contains(@class, "menu-bar_hoverable")][span[text()="File"]]' + ); + await clickXpath('//li[span[text()="New"]]'); + driver.switchTo() + .alert() + .accept(); + await findByXpath('//*[div[@class="scratchCategoryMenu"]]'); + await clickText('Operators', scope.blocksTab); + }); }); });